From b5357d873809c4ff25925a2d0c2e9e46d0382952 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 14 Aug 2012 13:17:32 +0400 Subject: [PATCH 01/36] Compile against 122.29 idea eap --- .../jetbrains/jet/asJava/ClsWrapperStubPsiFactory.java | 9 +++++++++ idea/src/META-INF/plugin.xml | 2 +- update_dependencies.xml | 8 ++++---- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/ClsWrapperStubPsiFactory.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/ClsWrapperStubPsiFactory.java index f53ee42206d..dbe6cb7dbdb 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/ClsWrapperStubPsiFactory.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/ClsWrapperStubPsiFactory.java @@ -140,4 +140,13 @@ class ClsWrapperStubPsiFactory extends StubPsiFactory { return delegate.createTypeParameterList(stub); } + @Override + public PsiAnnotationParameterList createAnnotationParameterList(PsiAnnotationParameterListStub stub) { + return delegate.createAnnotationParameterList(stub); + } + + @Override + public PsiNameValuePair createNameValuePair(PsiNameValuePairStub stub) { + return delegate.createNameValuePair(stub); + } } diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 08a696aa051..9b243c61055 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -6,7 +6,7 @@ @snapshot@ JetBrains Inc. - + JUnit diff --git a/update_dependencies.xml b/update_dependencies.xml index d0177c9f883..7cd49c0e8a0 100644 --- a/update_dependencies.xml +++ b/update_dependencies.xml @@ -3,15 +3,15 @@ From 9e5e6941da4a35a4d086a28304ecc16c76a3be51 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 14 Aug 2012 13:18:12 +0400 Subject: [PATCH 02/36] Control supported version manually --- pluginPublisher/TeamCityPluginPublisher.xml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/pluginPublisher/TeamCityPluginPublisher.xml b/pluginPublisher/TeamCityPluginPublisher.xml index 42077bada40..b1d684c6ce2 100644 --- a/pluginPublisher/TeamCityPluginPublisher.xml +++ b/pluginPublisher/TeamCityPluginPublisher.xml @@ -54,21 +54,6 @@ - - - - - - - - - - - - - - Date: Fri, 10 Aug 2012 14:23:16 +0400 Subject: [PATCH 03/36] Use internal namespace qualified name --- .../jet/lang/resolve/lazy/data/JetClassOrObjectInfo.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/data/JetClassOrObjectInfo.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/data/JetClassOrObjectInfo.java index 838755a6f4f..39c742037ee 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/data/JetClassOrObjectInfo.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/data/JetClassOrObjectInfo.java @@ -76,7 +76,8 @@ public abstract class JetClassOrObjectInfo implement PsiFile file = element.getContainingFile(); if (file instanceof JetFile) { JetFile jetFile = (JetFile) file; - return new FqName(jetFile.getNamespaceHeader().getQualifiedName()); + final JetNamespaceHeader header = jetFile.getNamespaceHeader(); + return header != null ? header.getFqName() : FqName.ROOT; } throw new IllegalArgumentException("Not in a JetFile: " + element); } From cf6787b79811d9b409adcbb8d23120c3df9f5165 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Fri, 10 Aug 2012 20:13:30 +0400 Subject: [PATCH 04/36] Inject context for body resolve --- .../jet/di/InjectorForTopDownAnalyzerForJvm.java | 1 + .../analyzer/AnalyzerFacadeForEverything.java | 5 +++-- .../jetbrains/jet/di/InjectorForBodyResolve.java | 11 ++++++++++- .../jet/di/InjectorForTopDownAnalyzerBasic.java | 1 + .../jetbrains/jet/lang/resolve/BodyResolver.java | 16 ++++++++++++---- .../jetbrains/jet/di/AllInjectorsGenerator.java | 1 + .../jet/di/InjectorForTopDownAnalyzerForJs.java | 1 + 7 files changed, 29 insertions(+), 7 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java index 184497cbcaa..c4905da5c37 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java @@ -144,6 +144,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly this.topDownAnalysisContext.setTopDownAnalysisParameters(topDownAnalysisParameters); this.bodyResolver.setCallResolver(callResolver); + this.bodyResolver.setContext(topDownAnalysisContext); this.bodyResolver.setControlFlowAnalyzer(controlFlowAnalyzer); this.bodyResolver.setDeclarationsChecker(declarationsChecker); this.bodyResolver.setDescriptorResolver(descriptorResolver); diff --git a/compiler/frontend/src/org/jetbrains/jet/analyzer/AnalyzerFacadeForEverything.java b/compiler/frontend/src/org/jetbrains/jet/analyzer/AnalyzerFacadeForEverything.java index 8e358e4e05d..978b57f8dcb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/analyzer/AnalyzerFacadeForEverything.java +++ b/compiler/frontend/src/org/jetbrains/jet/analyzer/AnalyzerFacadeForEverything.java @@ -49,10 +49,11 @@ public class AnalyzerFacadeForEverything { InjectorForBodyResolve injector = new InjectorForBodyResolve( project, topDownAnalysisParameters, - new ObservableBindingTrace(traceContext)); + new ObservableBindingTrace(traceContext), + bodiesResolveContext); try { - injector.getBodyResolver().resolveBodies(bodiesResolveContext); + injector.getBodyResolver().resolveBodies(); return AnalyzeExhaust.success(traceContext.getBindingContext()); } finally { injector.destroy(); diff --git a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForBodyResolve.java b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForBodyResolve.java index 83ecad21737..0f628e6a6a3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForBodyResolve.java +++ b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForBodyResolve.java @@ -21,6 +21,7 @@ import org.jetbrains.jet.lang.resolve.BodyResolver; import com.intellij.openapi.project.Project; import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters; import org.jetbrains.jet.lang.resolve.BindingTrace; +import org.jetbrains.jet.lang.resolve.BodiesResolveContext; import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.AnnotationResolver; @@ -42,6 +43,7 @@ public class InjectorForBodyResolve { private final Project project; private final TopDownAnalysisParameters topDownAnalysisParameters; private final BindingTrace bindingTrace; + private final BodiesResolveContext bodiesResolveContext; private CallResolver callResolver; private DescriptorResolver descriptorResolver; private AnnotationResolver annotationResolver; @@ -57,12 +59,14 @@ public class InjectorForBodyResolve { public InjectorForBodyResolve( @NotNull Project project, @NotNull TopDownAnalysisParameters topDownAnalysisParameters, - @NotNull BindingTrace bindingTrace + @NotNull BindingTrace bindingTrace, + @NotNull BodiesResolveContext bodiesResolveContext ) { this.bodyResolver = new BodyResolver(); this.project = project; this.topDownAnalysisParameters = topDownAnalysisParameters; this.bindingTrace = bindingTrace; + this.bodiesResolveContext = bodiesResolveContext; this.callResolver = new CallResolver(); this.descriptorResolver = new DescriptorResolver(); this.annotationResolver = new AnnotationResolver(); @@ -76,6 +80,7 @@ public class InjectorForBodyResolve { this.topDownAnalysisContext = new TopDownAnalysisContext(); this.bodyResolver.setCallResolver(callResolver); + this.bodyResolver.setContext(bodiesResolveContext); this.bodyResolver.setControlFlowAnalyzer(controlFlowAnalyzer); this.bodyResolver.setDeclarationsChecker(declarationsChecker); this.bodyResolver.setDescriptorResolver(descriptorResolver); @@ -138,4 +143,8 @@ public class InjectorForBodyResolve { return this.bindingTrace; } + public BodiesResolveContext getBodiesResolveContext() { + return this.bodiesResolveContext; + } + } diff --git a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerBasic.java b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerBasic.java index e2ea46757c7..4c29dd3d5ae 100644 --- a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerBasic.java +++ b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerBasic.java @@ -128,6 +128,7 @@ public class InjectorForTopDownAnalyzerBasic { this.topDownAnalysisContext.setTopDownAnalysisParameters(topDownAnalysisParameters); this.bodyResolver.setCallResolver(callResolver); + this.bodyResolver.setContext(topDownAnalysisContext); this.bodyResolver.setControlFlowAnalyzer(controlFlowAnalyzer); this.bodyResolver.setDeclarationsChecker(declarationsChecker); this.bodyResolver.setDescriptorResolver(descriptorResolver); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index 284c976b5a0..32ce7e4f36e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -110,6 +110,10 @@ public class BodyResolver { this.declarationsChecker = declarationsChecker; } + @Inject + public void setContext(@NotNull BodiesResolveContext context) { + this.context = context; + } private void resolveBehaviorDeclarationBodies(@NotNull BodiesResolveContext bodiesResolveContext) { // Initialize context @@ -132,10 +136,14 @@ public class BodyResolver { } public void resolveBodies(@NotNull BodiesResolveContext bodiesResolveContext) { - resolveBehaviorDeclarationBodies(bodiesResolveContext); - controlFlowAnalyzer.process(bodiesResolveContext); - declarationsChecker.process(bodiesResolveContext); + context = bodiesResolveContext; + resolveBodies(); + } + public void resolveBodies() { + resolveBehaviorDeclarationBodies(context); + controlFlowAnalyzer.process(context); + declarationsChecker.process(context); } private void resolveDelegationSpecifierLists() { @@ -482,7 +490,7 @@ public class BodyResolver { } } - private void resolveFunctionBody( + public void resolveFunctionBody( @NotNull BindingTrace trace, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor, diff --git a/injector-generator/src/org/jetbrains/jet/di/AllInjectorsGenerator.java b/injector-generator/src/org/jetbrains/jet/di/AllInjectorsGenerator.java index f3f137cd08c..b8908ea9ca9 100644 --- a/injector-generator/src/org/jetbrains/jet/di/AllInjectorsGenerator.java +++ b/injector-generator/src/org/jetbrains/jet/di/AllInjectorsGenerator.java @@ -222,6 +222,7 @@ public class AllInjectorsGenerator { generator.addPublicParameter(Project.class); generator.addPublicParameter(TopDownAnalysisParameters.class); generator.addPublicParameter(BindingTrace.class); + generator.addPublicParameter(BodiesResolveContext.class); generator.generate("compiler/frontend/src", "org.jetbrains.jet.di", "InjectorForBodyResolve"); } diff --git a/js/js.translator/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJs.java b/js/js.translator/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJs.java index 8c93376ad77..00e2a1badac 100644 --- a/js/js.translator/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJs.java +++ b/js/js.translator/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJs.java @@ -128,6 +128,7 @@ public class InjectorForTopDownAnalyzerForJs { this.topDownAnalysisContext.setTopDownAnalysisParameters(topDownAnalysisParameters); this.bodyResolver.setCallResolver(callResolver); + this.bodyResolver.setContext(topDownAnalysisContext); this.bodyResolver.setControlFlowAnalyzer(controlFlowAnalyzer); this.bodyResolver.setDeclarationsChecker(declarationsChecker); this.bodyResolver.setDescriptorResolver(descriptorResolver); From 4c39a49bd1c295fdd021b623f05735c4d592fe4c Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Fri, 10 Aug 2012 21:46:29 +0400 Subject: [PATCH 05/36] Go through the chain to find implicit receiver --- .../org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java index 5881ce61ec9..0accb3f1418 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java @@ -118,6 +118,12 @@ public class ChainedScope implements JetScope { @NotNull @Override public ReceiverDescriptor getImplicitReceiver() { + for (JetScope scope : scopeChain) { + if (scope.getImplicitReceiver() != ReceiverDescriptor.NO_RECEIVER) { + return scope.getImplicitReceiver(); + } + } + return ReceiverDescriptor.NO_RECEIVER; } From 365bb3ad8a47634e0085c0e8efb5ecde65d0e0f3 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Mon, 13 Aug 2012 16:06:28 +0400 Subject: [PATCH 06/36] Use lazy resolve in completion --- .../jet/cli/jvm/compiler/TipsManager.java | 11 +- .../resolve/lazy/LazyBindingContextUtils.java | 201 ++++++++++++++++++ .../jet/plugin/caches/JetShortNamesCache.java | 26 ++- .../JetClassCompletionContributor.java | 71 +++---- .../completion/JetCompletionContributor.java | 68 +++--- .../JetExtensionReceiverTypeContributor.java | 8 +- .../completion/JetPackagesContributor.java | 8 +- .../project/AnalyzerFacadeWithCache.java | 109 ++++++++-- .../project/WholeProjectAnalyzerFacade.java | 22 +- 9 files changed, 409 insertions(+), 115 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyBindingContextUtils.java diff --git a/compiler/backend/src/org/jetbrains/jet/cli/jvm/compiler/TipsManager.java b/compiler/backend/src/org/jetbrains/jet/cli/jvm/compiler/TipsManager.java index 9c625a867d1..d1040cbefc1 100644 --- a/compiler/backend/src/org/jetbrains/jet/cli/jvm/compiler/TipsManager.java +++ b/compiler/backend/src/org/jetbrains/jet/cli/jvm/compiler/TipsManager.java @@ -51,12 +51,15 @@ public final class TipsManager { } @NotNull - public static Collection getReferenceVariants(JetSimpleNameExpression expression, BindingContext context) { + public static Collection getReferenceVariants( + @NotNull final JetSimpleNameExpression expression, + @NotNull final BindingContext context + ) { JetExpression receiverExpression = expression.getReceiverExpression(); if (receiverExpression != null) { // Process as call expression - final JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression); - final JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression); + JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression); + JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression); if (expressionType != null && resolutionScope != null) { if (!(expressionType instanceof NamespaceType)) { @@ -116,7 +119,7 @@ public final class TipsManager { } @NotNull - public static Collection getReferenceVariants(JetNamespaceHeader expression, BindingContext context) { + public static Collection getPackageReferenceVariants(JetSimpleNameExpression expression, BindingContext context) { JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression); if (resolutionScope != null) { return excludeNonPackageDescriptors(resolutionScope.getAllDescriptors()); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyBindingContextUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyBindingContextUtils.java new file mode 100644 index 00000000000..654b936eb06 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyBindingContextUtils.java @@ -0,0 +1,201 @@ +/* + * Copyright 2010-2012 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.jet.lang.resolve.lazy; + +import com.google.common.base.Predicates; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.di.InjectorForBodyResolve; +import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.*; +import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.resolve.scopes.WritableScope; + +import java.util.Collection; +import java.util.Collections; +import java.util.Map; + +/** + * @author Nikolay Krasko + */ +public class LazyBindingContextUtils { + private static final Logger LOG = Logger.getInstance("#" + LazyBindingContextUtils.class.getName()); + + private LazyBindingContextUtils() { + } + + private static class EmptyBodyResolveContext implements BodiesResolveContext { + @Override + public Map getClasses() { + return Collections.emptyMap(); + } + + @Override + public Map getObjects() { + return Collections.emptyMap(); + } + + @Override + public Map getProperties() { + return Collections.emptyMap(); + } + + @Override + public Map getFunctions() { + return Collections.emptyMap(); + } + + @Override + public Map getDeclaringScopes() { + return Collections.emptyMap(); + } + + @Override + public Map getScripts() { + return Collections.emptyMap(); + } + + @Override + public Map getScriptScopes() { + return Collections.emptyMap(); + } + + @Override + public void setTopDownAnalysisParameters(TopDownAnalysisParameters parameters) { + } + + @Override + public boolean completeAnalysisNeeded(@NotNull PsiElement element) { + return true; + } + } + + public static @NotNull BindingContext getExpressionBindingContext(@NotNull ResolveSession resolveSession, @NotNull JetExpression expression) { + final DelegatingBindingTrace trace = new DelegatingBindingTrace(resolveSession.getBindingContext()); + + JetFile file = (JetFile) expression.getContainingFile(); + + // Resolve enclosing function body + JetNamedFunction namedFunction = PsiTreeUtil.getTopmostParentOfType(expression, JetNamedFunction.class); + if (namedFunction != null) { + TopDownAnalysisParameters parameters = new TopDownAnalysisParameters( + Predicates.alwaysTrue(), false, true, Collections.emptyList()); + + InjectorForBodyResolve bodyResolve = new InjectorForBodyResolve(file.getProject(), parameters, trace, new EmptyBodyResolveContext()); + + final BodyResolver bodyResolver = bodyResolve.getBodyResolver(); + + if (namedFunction.getParent() instanceof JetFile || + namedFunction.getParent() instanceof JetClassBody || + namedFunction.getParent() instanceof JetClassObject) { + JetScope scope = resolveSession.getResolutionScope(namedFunction); + FunctionDescriptor functionDescriptor = (FunctionDescriptor) resolveSession.resolveToDescriptor(namedFunction); + bodyResolver.resolveFunctionBody(trace, namedFunction, functionDescriptor, scope); + } + else { + LOG.warn(String.format("Not expected parent for function: %s in %s", + namedFunction.getName(), namedFunction.getContainingFile())); + } + } + + if (trace.getBindingContext().get(BindingContext.RESOLUTION_SCOPE, expression) == null) { + JetScope scope = getExpressionMemberScope(resolveSession, expression); + if (scope != null) { + trace.record(BindingContext.RESOLUTION_SCOPE, expression, scope); + } + } + + return trace.getBindingContext(); + } + + private static JetScope getExpressionOuterScope(@NotNull ResolveSession resolveSession, @NotNull JetExpression expression) { + JetDeclaration parentDeclaration = PsiTreeUtil.getParentOfType(expression, JetDeclaration.class); + // DeclarationDescriptor descriptor = resolveToDescriptor(parentDeclaration); + return resolveSession.getResolutionScope(parentDeclaration); + } + + public static JetScope getExpressionMemberScope(@NotNull ResolveSession resolveSession, @NotNull JetExpression expression) { + DelegatingBindingTrace trace = new DelegatingBindingTrace(resolveSession.getBindingContext()); + + if (expression instanceof JetReferenceExpression) { + // In some type declaration + if (expression.getParent() instanceof JetUserType) { + JetUserType qualifier = ((JetUserType) expression.getParent()).getQualifier(); + if (qualifier != null) { + Collection descriptors = resolveSession.getInjector().getQualifiedExpressionResolver() + .lookupDescriptorsForUserType(qualifier, getExpressionOuterScope(resolveSession, expression), trace); + + for (DeclarationDescriptor descriptor : descriptors) { + if (descriptor instanceof LazyPackageDescriptor) { + return ((LazyPackageDescriptor) descriptor).getMemberScope(); + } + + } + } + } + + // Inside import + if (PsiTreeUtil.getParentOfType(expression, JetImportDirective.class, false) != null) { + if (expression.getParent() instanceof JetDotQualifiedExpression) { + JetExpression element = ((JetDotQualifiedExpression) expression.getParent()).getReceiverExpression(); + + NamespaceDescriptor filePackage = resolveSession.getPackageDescriptorByFqName( + new FqName(((JetFile) expression.getContainingFile()).getPackageName())); + + NamespaceDescriptor rootPackage = resolveSession.getPackageDescriptorByFqName(FqName.ROOT); + + Collection descriptors; + + if (element instanceof JetDotQualifiedExpression) { + descriptors = resolveSession.getInjector().getQualifiedExpressionResolver().lookupDescriptorsForQualifiedExpression( + (JetDotQualifiedExpression) element, rootPackage.getMemberScope(), filePackage.getMemberScope(), trace, false, false); + } + else { + descriptors = resolveSession.getInjector().getQualifiedExpressionResolver().lookupDescriptorsForSimpleNameReference( + (JetSimpleNameExpression) element, rootPackage.getMemberScope(), filePackage.getMemberScope(), trace, false, false, false); + } + + for (DeclarationDescriptor descriptor : descriptors) { + if (descriptor instanceof NamespaceDescriptor) { + return ((NamespaceDescriptor) descriptor).getMemberScope(); + } + } + } + else { + return resolveSession.getPackageDescriptorByFqName(FqName.ROOT).getMemberScope(); + } + } + + // Inside package declaration + JetNamespaceHeader namespaceHeader = PsiTreeUtil.getParentOfType(expression, JetNamespaceHeader.class, false); + if (namespaceHeader != null) { + NamespaceDescriptor packageDescriptor = resolveSession.getPackageDescriptorByFqName( + namespaceHeader.getParentFqName((JetReferenceExpression)expression)); + if (packageDescriptor != null) { + return packageDescriptor.getMemberScope(); + } + } + } + + return null; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java index ccf3905c1d8..438c428bf8d 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java @@ -18,6 +18,7 @@ package org.jetbrains.jet.plugin.caches; import com.google.common.base.Function; import com.google.common.collect.Collections2; +import com.google.common.collect.Sets; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.psi.PsiClass; @@ -39,6 +40,8 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTraceContext; import org.jetbrains.jet.lang.resolve.ImportPath; import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver; +import org.jetbrains.jet.lang.resolve.lazy.LazyBindingContextUtils; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.JetType; @@ -155,22 +158,25 @@ public class JetShortNamesCache extends PsiShortNamesCache { @NotNull JetSimpleNameExpression expression, @NotNull GlobalSearchScope scope ) { - HashSet result = new HashSet(); - JetFile jetFile = (JetFile) expression.getContainingFile(); - BindingContext context = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(jetFile).getBindingContext(); + final ResolveSession resolveSessionForFile = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile(jetFile); + LazyBindingContextUtils.getExpressionBindingContext(resolveSessionForFile, expression); + BindingContext context = WholeProjectAnalyzerFacade.getLazyResolveContext(jetFile, expression); JetScope jetScope = context.get(BindingContext.RESOLUTION_SCOPE, expression); if (jetScope == null) { - return result; + return Collections.emptyList(); } + Set result = Sets.newHashSet(); + Collection topLevelFunctionPrototypes = JetFromJavaDescriptorHelper.getTopLevelFunctionPrototypesByName(name, project, scope); for (PsiMethod method : topLevelFunctionPrototypes) { FqName functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN(method); if (functionFQN != null) { JetImportDirective importDirective = JetPsiFactory.createImportDirective(project, new ImportPath(functionFQN, false)); - Collection declarationDescriptors = new QualifiedExpressionResolver().analyseImportReference(importDirective, jetScope, new BindingTraceContext()); + Collection declarationDescriptors = new QualifiedExpressionResolver().analyseImportReference( + importDirective, jetScope, new BindingTraceContext()); for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) { if (declarationDescriptor instanceof FunctionDescriptor) { result.add((FunctionDescriptor) declarationDescriptor); @@ -181,10 +187,8 @@ public class JetShortNamesCache extends PsiShortNamesCache { Collection jetNamedFunctions = JetShortFunctionNameIndex.getInstance().get(name, project, scope); for (JetNamedFunction jetNamedFunction : jetNamedFunctions) { - SimpleFunctionDescriptor functionDescriptor = context.get(BindingContext.FUNCTION, jetNamedFunction); - if (functionDescriptor != null) { - result.add(functionDescriptor); - } + FunctionDescriptor functionDescriptor = (FunctionDescriptor) resolveSessionForFile.resolveToDescriptor(jetNamedFunction); + result.add(functionDescriptor); } return result; @@ -224,7 +228,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { JetFile jetFile = (JetFile) expression.getContainingFile(); - BindingContext context = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(jetFile).getBindingContext(); + BindingContext context = WholeProjectAnalyzerFacade.getLazyResolveContext(jetFile, expression); JetExpression receiverExpression = expression.getReceiverExpression(); if (receiverExpression != null) { @@ -273,7 +277,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { @NotNull Condition acceptedShortNameCondition, @NotNull JetFile jetFile ) { - BindingContext context = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(jetFile).getBindingContext(); + BindingContext context = WholeProjectAnalyzerFacade.getLazyResolveContext(jetFile, null); Collection classDescriptors = new ArrayList(); for (String fqName : JetFullClassNameIndex.getInstance().getAllKeys(project)) { diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetClassCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetClassCompletionContributor.java index 8b7e9a18138..561aad3ebf3 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetClassCompletionContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetClassCompletionContributor.java @@ -21,18 +21,23 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiFile; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.Consumer; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.asJava.JetLightClass; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.psi.JetClassOrObject; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.plugin.caches.JetCacheManager; import org.jetbrains.jet.plugin.caches.JetShortNamesCache; import org.jetbrains.jet.plugin.completion.handlers.JetJavaClassInsertHandler; import org.jetbrains.jet.plugin.project.JsModuleDetector; import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; +import org.jetbrains.jet.plugin.stubindex.JetFullClassNameIndex; import java.util.Collection; @@ -40,34 +45,7 @@ import java.util.Collection; * @author Nikolay Krasko */ public class JetClassCompletionContributor extends CompletionContributor { - public JetClassCompletionContributor() { - // Should be removed in new idea - //extend(CompletionType.CLASS_NAME, PlatformPatterns.psiElement(), - // new CompletionProvider() { - // @Override - // protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, - // final @NotNull CompletionResultSet result) { - // final CompletionResultSet jetResult = JetCompletionSorting.addJetSorting(parameters, result); - // - // final PsiElement position = parameters.getPosition(); - // if (!(position.getContainingFile() instanceof JetFile)) { - // return; - // } - // - // final PsiReference ref = position.getContainingFile().findReferenceAt(parameters.getOffset()); - // if (ref instanceof JetSimpleNameReference) { - // addClasses(parameters, result, new Consumer() { - // @Override - // public void consume(LookupElement lookupElement) { - // jetResult.addElement(lookupElement); - // } - // }); - // } - // - // result.stopHere(); - // } - // }); - } + public JetClassCompletionContributor() {} /** * Jet classes will be added as java completions for unification @@ -75,17 +53,14 @@ public class JetClassCompletionContributor extends CompletionContributor { static void addClasses( @NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result, + @NotNull final BindingContext jetContext, @NotNull final Consumer consumer ) { CompletionResultSet tempResult = result.withPrefixMatcher(CompletionUtil.findReferenceOrAlphanumericPrefix(parameters)); - // TODO: Make icon for standard types final Collection jetOnlyClasses = JetShortNamesCache.getJetOnlyTypes(); - final BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile( - (JetFile)parameters.getPosition().getContainingFile()).getBindingContext(); - for (DeclarationDescriptor jetOnlyClass : jetOnlyClasses) { - consumer.consume(DescriptorLookupConverter.createLookupElement(bindingContext, jetOnlyClass)); + consumer.consume(DescriptorLookupConverter.createLookupElement(jetContext, jetOnlyClass)); } if (!JsModuleDetector.isJsModule((JetFile)parameters.getOriginalFile())) { @@ -99,8 +74,8 @@ public class JetClassCompletionContributor extends CompletionContributor { if (lookupElement instanceof JavaPsiClassReferenceElement) { JavaPsiClassReferenceElement javaPsiReferenceElement = (JavaPsiClassReferenceElement) lookupElement; - PsiClass object = javaPsiReferenceElement.getObject(); - if (addAsJetLookupElement(object, bindingContext, consumer)) { + PsiClass psiClass = javaPsiReferenceElement.getObject(); + if (addAsJetLookupElement(parameters, psiClass, consumer)) { return; } @@ -124,20 +99,30 @@ public class JetClassCompletionContributor extends CompletionContributor { (JetFile) parameters.getOriginalFile()); for (ClassDescriptor descriptor : descriptors) { - consumer.consume(DescriptorLookupConverter.createLookupElement(bindingContext, descriptor)); + consumer.consume(DescriptorLookupConverter.createLookupElement(jetContext, descriptor)); } } } - private static boolean addAsJetLookupElement(PsiClass aClass, BindingContext bindingContext, Consumer consumer) { + private static boolean addAsJetLookupElement(CompletionParameters parameters, PsiClass aClass, Consumer consumer) { if (aClass instanceof JetLightClass) { - ClassDescriptor descriptor = bindingContext.get( - BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, ((JetLightClass)aClass).getFqName()); + Project project = parameters.getPosition().getProject(); + PsiFile completionFile = parameters.getPosition().getContainingFile(); - if (descriptor != null) { - LookupElement element = DescriptorLookupConverter.createLookupElement(bindingContext, descriptor); - consumer.consume(element); - return true; + Collection classOrObjects = + JetFullClassNameIndex.getInstance().get(aClass.getQualifiedName(), project, GlobalSearchScope.allScope(project)); + + for (JetClassOrObject classOrObject : classOrObjects) { + if (classOrObject.getContainingFile().getOriginalFile().equals(aClass.getContainingFile())) { + PsiFile fileOfClass = completionFile.getOriginalFile().equals(aClass.getContainingFile()) ? completionFile : aClass.getContainingFile(); + + ResolveSession resolveSessionForFile = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) fileOfClass); + ClassDescriptor descriptor = resolveSessionForFile.getClassDescriptor(classOrObject); + + LookupElement element = DescriptorLookupConverter.createLookupElement(resolveSessionForFile.getBindingContext(), descriptor); + consumer.consume(element); + return true; + } } } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java index c70ca9b9fa2..e1f0cf5d72c 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java @@ -77,20 +77,18 @@ public class JetCompletionContributor extends CompletionContributor { JetSimpleNameReference jetReference = getJetReference(parameters); if (jetReference != null) { - - BindingContext jetContext = - WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile)position.getContainingFile()) - .getBindingContext(); + BindingContext jetContext = WholeProjectAnalyzerFacade.getLazyResolveContext( + (JetFile) position.getContainingFile(), jetReference.getExpression()); JetScope scope = jetContext.get(BindingContext.RESOLUTION_SCOPE, jetReference.getExpression()); session.inDescriptor = scope != null ? scope.getContainingDeclaration() : null; - completeForReference(parameters, result, position, jetReference, session); + completeForReference(parameters, result, position, jetReference, session, jetContext); if (!session.isSomethingAdded && session.customInvocationCount == 0) { // Rerun completion if nothing was found session.customInvocationCount = 1; - completeForReference(parameters, result, position, jetReference, session); + completeForReference(parameters, result, position, jetReference, session, jetContext); } } @@ -105,18 +103,18 @@ public class JetCompletionContributor extends CompletionContributor { @NotNull CompletionResultSet result, @NotNull PsiElement position, @NotNull JetSimpleNameReference jetReference, - @NotNull CompletionSession session - ) { + @NotNull CompletionSession session, + BindingContext jetContext) { if (isOnlyKeywordCompletion(position)) { return; } if (shouldRunTypeCompletionOnly(position, jetReference)) { if (session.customInvocationCount > 0) { - addClasses(parameters, result, session); + addClasses(parameters, result, session, jetContext); } else { - for (LookupElement variant : getReferenceVariants(jetReference, result, session)) { + for (LookupElement variant : getReferenceVariants(jetReference, result, session, jetContext)) { if (isTypeDeclaration(variant)) { addCheckedCompletionToResult(result, variant, session); } @@ -126,7 +124,7 @@ public class JetCompletionContributor extends CompletionContributor { return; } - for (LookupElement variant : getReferenceVariants(jetReference, result, session)) { + for (LookupElement variant : getReferenceVariants(jetReference, result, session, jetContext)) { addCheckedCompletionToResult(result, variant, session); } @@ -144,7 +142,7 @@ public class JetCompletionContributor extends CompletionContributor { } if (shouldRunTopLevelCompletion(parameters, session)) { - addClasses(parameters, result, session); + addClasses(parameters, result, session, jetContext); addJetTopLevelFunctions(jetReference.getExpression(), result, position, session); } @@ -157,12 +155,12 @@ public class JetCompletionContributor extends CompletionContributor { return PsiTreeUtil.getParentOfType(position, JetModifierList.class) != null; } - private static void addJetExtensions(JetSimpleNameExpression expression, CompletionResultSet result, PsiElement position) { + private static void addJetExtensions(@NotNull JetSimpleNameExpression expression, @NotNull CompletionResultSet result, @NotNull PsiElement position) { final PrefixMatcher prefixMatcher = result.getPrefixMatcher(); JetShortNamesCache namesCache = JetCacheManager.getInstance(position.getProject()).getNamesCache(); Condition matchPrefixCondition = new Condition() { @Override - public boolean value(String callableName) { + public boolean value(@NotNull String callableName) { return prefixMatcher.prefixMatches(callableName); } }; @@ -170,8 +168,8 @@ public class JetCompletionContributor extends CompletionContributor { Collection jetCallableExtensions = namesCache.getJetCallableExtensions( matchPrefixCondition, expression, GlobalSearchScope.allScope(position.getProject())); - BindingContext context = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile)position.getContainingFile()) - .getBindingContext(); + BindingContext context = WholeProjectAnalyzerFacade.getLazyResolveContext( + (JetFile) position.getContainingFile(), expression); for (DeclarationDescriptor jetCallableExtension : jetCallableExtensions) { result.addElement(DescriptorLookupConverter.createLookupElement(context, jetCallableExtension)); @@ -192,11 +190,10 @@ public class JetCompletionContributor extends CompletionContributor { return false; } - private static void addJetTopLevelFunctions(JetSimpleNameExpression expression, + private static void addJetTopLevelFunctions(@NotNull JetSimpleNameExpression expression, @NotNull CompletionResultSet result, @NotNull PsiElement position, @NotNull CompletionSession session) { - String actualPrefix = result.getPrefixMatcher().getPrefix(); Project project = position.getProject(); @@ -205,8 +202,8 @@ public class JetCompletionContributor extends CompletionContributor { GlobalSearchScope scope = GlobalSearchScope.allScope(project); Collection functionNames = namesCache.getAllTopLevelFunctionNames(); - BindingContext resolutionContext = - WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile)position.getContainingFile()).getBindingContext(); + BindingContext resolutionContext = WholeProjectAnalyzerFacade.getLazyResolveContext( + (JetFile) position.getContainingFile(), expression); for (String name : functionNames) { if (name.contains(actualPrefix)) { @@ -223,9 +220,9 @@ public class JetCompletionContributor extends CompletionContributor { private static void addClasses( @NotNull CompletionParameters parameters, @NotNull final CompletionResultSet result, - @NotNull final CompletionSession session - ) { - JetClassCompletionContributor.addClasses(parameters, result, new Consumer() { + @NotNull final CompletionSession session, + BindingContext jetContext) { + JetClassCompletionContributor.addClasses(parameters, result, jetContext, new Consumer() { @Override public void consume(@NotNull LookupElement element) { addCompletionToResult(result, element, session); @@ -233,7 +230,7 @@ public class JetCompletionContributor extends CompletionContributor { }); } - private static boolean shouldRunTypeCompletionOnly(PsiElement position, JetSimpleNameReference jetReference) { + private static boolean shouldRunTypeCompletionOnly(PsiElement position, @NotNull JetSimpleNameReference jetReference) { // Check that completion in the type annotation context and if there's a qualified // expression we are at first of it JetTypeReference typeReference = PsiTreeUtil.getParentOfType(position, JetTypeReference.class); @@ -245,7 +242,7 @@ public class JetCompletionContributor extends CompletionContributor { return false; } - private static boolean shouldRunTopLevelCompletion(@NotNull CompletionParameters parameters, CompletionSession session) { + private static boolean shouldRunTopLevelCompletion(@NotNull CompletionParameters parameters, @NotNull CompletionSession session) { if (session.customInvocationCount == 0) { return false; } @@ -263,7 +260,7 @@ public class JetCompletionContributor extends CompletionContributor { return false; } - private static boolean shouldRunExtensionsCompletion(CompletionParameters parameters, String prefix, CompletionSession session) { + private static boolean shouldRunExtensionsCompletion(@NotNull CompletionParameters parameters, @NotNull String prefix, @NotNull CompletionSession session) { if (session.customInvocationCount == 0 && prefix.length() < 3) { return false; } @@ -312,7 +309,7 @@ public class JetCompletionContributor extends CompletionContributor { session.isSomethingAdded = true; } - private static boolean isVisibleElement(LookupElement element, CompletionSession session) { + private static boolean isVisibleElement(@NotNull LookupElement element, @NotNull CompletionSession session) { if (session.inDescriptor != null) { if (element.getObject() instanceof JetLookupObject) { JetLookupObject jetObject = (JetLookupObject)element.getObject(); @@ -324,14 +321,16 @@ public class JetCompletionContributor extends CompletionContributor { return true; } - private static boolean isVisibleDescriptor(DeclarationDescriptor descriptor, CompletionSession session) { + private static boolean isVisibleDescriptor(DeclarationDescriptor descriptor, @NotNull CompletionSession session) { if (session.customInvocationCount >= 2) { // Show everything if user insist on showing completion list return true; } if (descriptor instanceof DeclarationDescriptorWithVisibility) { - return Visibilities.isVisible((DeclarationDescriptorWithVisibility)descriptor, session.inDescriptor); + if (session.inDescriptor != null) { + return Visibilities.isVisible((DeclarationDescriptorWithVisibility)descriptor, session.inDescriptor); + } } return true; @@ -341,13 +340,10 @@ public class JetCompletionContributor extends CompletionContributor { private static LookupElement[] getReferenceVariants( @NotNull JetSimpleNameReference reference, @NotNull final CompletionResultSet result, - @NotNull final CompletionSession session + @NotNull final CompletionSession session, + BindingContext jetContext ) { - BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile( - (JetFile)reference.getExpression().getContainingFile()) - .getBindingContext(); - - Collection descriptors = TipsManager.getReferenceVariants(reference.getExpression(), bindingContext); + Collection descriptors = TipsManager.getReferenceVariants(reference.getExpression(), jetContext); Collection checkedDescriptors = Collections2.filter(descriptors, new Predicate() { @Override @@ -360,6 +356,6 @@ public class JetCompletionContributor extends CompletionContributor { } }); - return DescriptorLookupConverter.collectLookupElements(bindingContext, checkedDescriptors); + return DescriptorLookupConverter.collectLookupElements(jetContext, checkedDescriptors); } } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetExtensionReceiverTypeContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetExtensionReceiverTypeContributor.java index 664584407c5..7d7b92482b5 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetExtensionReceiverTypeContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetExtensionReceiverTypeContributor.java @@ -24,7 +24,10 @@ import com.intellij.psi.PsiElement; import com.intellij.util.Consumer; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lexer.JetTokens; +import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; /** * Special contributor for getting completion of type for extensions receiver. @@ -38,8 +41,11 @@ public class JetExtensionReceiverTypeContributor extends CompletionContributor { ProcessingContext context, final @NotNull CompletionResultSet result ) { + BindingContext jetContext = WholeProjectAnalyzerFacade + .getLazyResolveContext((JetFile) parameters.getPosition().getContainingFile(), null); + if (parameters.getInvocationCount() > 0 || parameters.getCompletionType() == CompletionType.CLASS_NAME) { - JetClassCompletionContributor.addClasses(parameters, result, new Consumer() { + JetClassCompletionContributor.addClasses(parameters, result, jetContext, new Consumer() { @Override public void consume(@NotNull LookupElement element) { result.addElement(element); diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.java index 955a72f1568..144c89ec9a0 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.java @@ -71,12 +71,11 @@ public class JetPackagesContributor extends CompletionContributor { int prefixLength = parameters.getOffset() - simpleNameReference.getExpression().getTextOffset(); result = result.withPrefixMatcher(new PlainPrefixMatcher(name.substring(0, prefixLength))); - BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile( - (JetFile)namespaceHeader.getContainingFile()) - .getBindingContext(); + BindingContext bindingContext = WholeProjectAnalyzerFacade.getLazyResolveContext( + (JetFile) namespaceHeader.getContainingFile(), simpleNameReference.getExpression()); for (LookupElement variant : DescriptorLookupConverter.collectLookupElements( - bindingContext, TipsManager.getReferenceVariants(namespaceHeader, bindingContext))) { + bindingContext, TipsManager.getPackageReferenceVariants(simpleNameReference.getExpression(), bindingContext))) { if (!variant.getLookupString().contains(DUMMY_IDENTIFIER)) { result.addElement(variant); } @@ -92,5 +91,6 @@ public class JetPackagesContributor extends CompletionContributor { public void beforeCompletion(@NotNull CompletionInitializationContext context) { // Will need to filter this dummy identifier to avoid showing it in completion context.setDummyIdentifier(DUMMY_IDENTIFIER); + // context.setDummyIdentifier(CompletionInitializationContext.DUMMY_IDENTIFIER); } } diff --git a/idea/src/org/jetbrains/jet/plugin/project/AnalyzerFacadeWithCache.java b/idea/src/org/jetbrains/jet/plugin/project/AnalyzerFacadeWithCache.java index 4bc6ffc70d7..6f394b83cad 100644 --- a/idea/src/org/jetbrains/jet/plugin/project/AnalyzerFacadeWithCache.java +++ b/idea/src/org/jetbrains/jet/plugin/project/AnalyzerFacadeWithCache.java @@ -18,33 +18,43 @@ package org.jetbrains.jet.plugin.project; import com.google.common.base.Predicate; import com.google.common.base.Predicates; +import com.google.common.collect.Lists; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.psi.impl.PsiModificationTrackerImpl; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.CachedValue; import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; import com.intellij.psi.util.PsiModificationTracker; import com.intellij.util.Function; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.analyzer.AnalyzeExhaust; +import org.jetbrains.jet.di.InjectorForJavaDescriptorResolver; +import org.jetbrains.jet.lang.BuiltinsScopeExtensionMode; +import org.jetbrains.jet.lang.DefaultModuleConfiguration; +import org.jetbrains.jet.lang.ModuleConfiguration; +import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.psi.JetFile; -import org.jetbrains.jet.lang.psi.JetPsiUtil; -import org.jetbrains.jet.lang.resolve.AnalyzerScriptParameter; -import org.jetbrains.jet.lang.resolve.BindingTraceContext; -import org.jetbrains.jet.lang.resolve.BodiesResolveContext; -import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace; -import org.jetbrains.jet.lang.resolve.java.JetFilesProvider; +import org.jetbrains.jet.lang.psi.JetImportDirective; +import org.jetbrains.jet.lang.psi.JetPsiFactory; +import org.jetbrains.jet.lang.resolve.*; +import org.jetbrains.jet.lang.resolve.java.*; +import org.jetbrains.jet.lang.resolve.lazy.FileBasedDeclarationProviderFactory; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.lang.resolve.scopes.WritableScope; +import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; -import java.util.Collection; -import java.util.Collections; +import java.util.*; /** * @author Pavel Talanov @@ -55,6 +65,7 @@ public final class AnalyzerFacadeWithCache { private final static Key> ANALYZE_EXHAUST_HEADERS = Key.create("ANALYZE_EXHAUST_HEADERS"); private final static Key> ANALYZE_EXHAUST_FULL = Key.create("ANALYZE_EXHAUST_FULL"); + private final static Key> ANALYZE_EXHAUST_LAZY_FULL = Key.create("ANALYZE_EXHAUST_FULL"); private static final Object lock = new Object(); public static final Function> SINGLE_DECLARATION_PROVIDER = new Function>() { @@ -67,7 +78,6 @@ public final class AnalyzerFacadeWithCache { private AnalyzerFacadeWithCache() { } - /** * Analyze project with string cache for given file. Given file will be fully analyzed. * @@ -88,8 +98,6 @@ public final class AnalyzerFacadeWithCache { @Override public Result compute() { try { - // System.out.println("===============ReCache - In-Block=============="); - // Collect context for headers first AnalyzeExhaust analyzeExhaustHeaders = analyzeHeadersWithCacheOnFile(file, declarationProvider); @@ -149,7 +157,6 @@ public final class AnalyzerFacadeWithCache { CachedValuesManager.getManager(fileToCache.getProject()).createCachedValue(new CachedValueProvider() { @Override public Result compute() { - // System.out.println("===============ReCache - OUT-OF-BLOCK=============="); AnalyzeExhaust exhaust = AnalyzerFacadeProvider.getAnalyzerFacadeForFile(fileToCache) .analyzeFiles(fileToCache.getProject(), declarationProvider.fun(fileToCache), @@ -169,4 +176,80 @@ public final class AnalyzerFacadeWithCache { DiagnosticUtils.throwIfRunningOnServer(e); LOG.error(e); } + + private static final Object lazyLock = new Object(); + + @NotNull + public static ResolveSession getLazyResolveSession(@NotNull final JetFile file) { + synchronized (lazyLock) { + final Project fileProject = file.getProject(); + CachedValue bindingContextCachedValue = file.getUserData(ANALYZE_EXHAUST_LAZY_FULL); + if (bindingContextCachedValue == null) { + bindingContextCachedValue = + CachedValuesManager.getManager(file.getProject()).createCachedValue(new CachedValueProvider() { + @Override + public Result compute() { + ModuleDescriptor javaModule = new ModuleDescriptor(Name.special("")); + + InjectorForJavaDescriptorResolver injector = new InjectorForJavaDescriptorResolver( + fileProject, new BindingTraceContext(), javaModule, BuiltinsScopeExtensionMode.ALL); + + List files = JetFilesProvider.getInstance(fileProject).allInScope(GlobalSearchScope.allScope(fileProject)); + + // Given file can differ from the original because it can be a virtual copy with some modifications + JetFile originalFile = (JetFile) file.getOriginalFile(); + files.remove(originalFile); + files.add(file); + + final PsiClassFinder psiClassFinder = injector.getPsiClassFinder(); + + // TODO: Replace with stub declaration provider + final FileBasedDeclarationProviderFactory declarationProviderFactory = new FileBasedDeclarationProviderFactory(files, new Predicate() { + @Override + public boolean apply(FqName fqName) { + return psiClassFinder.findPsiPackage(fqName) != null || new FqName("jet").equals(fqName); + } + }); + + final JavaDescriptorResolver javaDescriptorResolver = injector.getJavaDescriptorResolver(); + + ModuleConfiguration moduleConfiguration = new ModuleConfiguration() { + @Override + public void addDefaultImports(@NotNull Collection directives) { + final Collection defaultImports = Lists.newArrayList(JavaBridgeConfiguration.DEFAULT_JAVA_IMPORTS); + defaultImports.addAll(Arrays.asList(DefaultModuleConfiguration.DEFAULT_JET_IMPORTS)); + + for (ImportPath defaultJetImport : defaultImports) { + directives.add(JetPsiFactory.createImportDirective(fileProject, defaultJetImport)); + } + } + + @Override + public void extendNamespaceScope( + @NotNull BindingTrace trace, + @NotNull NamespaceDescriptor namespaceDescriptor, + @NotNull WritableScope namespaceMemberScope + ) { + FqName fqName = DescriptorUtils.getFQName(namespaceDescriptor).toSafe(); + if (new FqName("jet").equals(fqName)) { + namespaceMemberScope.importScope(JetStandardLibrary.getInstance().getLibraryScope()); + } + if (psiClassFinder.findPsiPackage(fqName) != null) { + JavaPackageScope javaPackageScope = javaDescriptorResolver.getJavaPackageScope(fqName, namespaceDescriptor); + namespaceMemberScope.importScope(javaPackageScope); + } + } + }; + + ModuleDescriptor lazyModule = new ModuleDescriptor(Name.special("")); + ResolveSession resolveSession = new ResolveSession(fileProject, lazyModule, moduleConfiguration, declarationProviderFactory); + + return new Result(resolveSession, PsiModificationTracker.MODIFICATION_COUNT); + } + }, false); + file.putUserData(ANALYZE_EXHAUST_LAZY_FULL, bindingContextCachedValue); + } + return bindingContextCachedValue.getValue(); + } + } } diff --git a/idea/src/org/jetbrains/jet/plugin/project/WholeProjectAnalyzerFacade.java b/idea/src/org/jetbrains/jet/plugin/project/WholeProjectAnalyzerFacade.java index 9b399be0311..51b1c6035bc 100644 --- a/idea/src/org/jetbrains/jet/plugin/project/WholeProjectAnalyzerFacade.java +++ b/idea/src/org/jetbrains/jet/plugin/project/WholeProjectAnalyzerFacade.java @@ -17,20 +17,23 @@ package org.jetbrains.jet.plugin.project; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.analyzer.AnalyzeExhaust; +import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.java.JetFilesProvider; +import org.jetbrains.jet.lang.resolve.lazy.LazyBindingContextUtils; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import static org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache.analyzeFileWithCache; +import static org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache.getLazyResolveSession; /** * @author abreslav */ public final class WholeProjectAnalyzerFacade { - /** - * Forbid creating - */ private WholeProjectAnalyzerFacade() { } @@ -38,4 +41,17 @@ public final class WholeProjectAnalyzerFacade { public static AnalyzeExhaust analyzeProjectWithCacheOnAFile(@NotNull JetFile file) { return analyzeFileWithCache(file, JetFilesProvider.getInstance(file.getProject()).sampleToAllFilesInModule()); } + + @NotNull + public static ResolveSession getLazyResolveSessionForFile(@NotNull JetFile file) { + return getLazyResolveSession(file); + } + + @NotNull + public static BindingContext getLazyResolveContext(@NotNull JetFile file, @Nullable JetExpression expression) { + ResolveSession resolveSession = getLazyResolveSessionForFile(file); + return expression != null ? + LazyBindingContextUtils.getExpressionBindingContext(resolveSession, expression) : + resolveSession.getBindingContext(); + } } From d1dc67c0490325ad92a0776c7208b156aaff5259 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Mon, 13 Aug 2012 20:13:25 +0400 Subject: [PATCH 07/36] Search for function in resolve session with non-physical file --- .../jet/plugin/caches/JetShortNamesCache.java | 11 ++++++----- .../completion/basic/multifile/TopLevelFunction-1.kt | 2 +- .../completion/basic/multifile/TopLevelFunction-2.kt | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java index 438c428bf8d..5116f5d5dee 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java @@ -34,13 +34,15 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.asJava.JavaElementFinder; -import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.descriptors.CallableDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTraceContext; import org.jetbrains.jet.lang.resolve.ImportPath; import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver; -import org.jetbrains.jet.lang.resolve.lazy.LazyBindingContextUtils; import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.scopes.JetScope; @@ -159,8 +161,6 @@ public class JetShortNamesCache extends PsiShortNamesCache { @NotNull GlobalSearchScope scope ) { JetFile jetFile = (JetFile) expression.getContainingFile(); - final ResolveSession resolveSessionForFile = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile(jetFile); - LazyBindingContextUtils.getExpressionBindingContext(resolveSessionForFile, expression); BindingContext context = WholeProjectAnalyzerFacade.getLazyResolveContext(jetFile, expression); JetScope jetScope = context.get(BindingContext.RESOLUTION_SCOPE, expression); @@ -187,7 +187,8 @@ public class JetShortNamesCache extends PsiShortNamesCache { Collection jetNamedFunctions = JetShortFunctionNameIndex.getInstance().get(name, project, scope); for (JetNamedFunction jetNamedFunction : jetNamedFunctions) { - FunctionDescriptor functionDescriptor = (FunctionDescriptor) resolveSessionForFile.resolveToDescriptor(jetNamedFunction); + ResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile)jetNamedFunction.getContainingFile()); + FunctionDescriptor functionDescriptor = (FunctionDescriptor) resolveSession.resolveToDescriptor(jetNamedFunction); result.add(functionDescriptor); } diff --git a/idea/testData/completion/basic/multifile/TopLevelFunction-1.kt b/idea/testData/completion/basic/multifile/TopLevelFunction-1.kt index 67896eb1d9c..46b8d84fb95 100644 --- a/idea/testData/completion/basic/multifile/TopLevelFunction-1.kt +++ b/idea/testData/completion/basic/multifile/TopLevelFunction-1.kt @@ -1,7 +1,7 @@ package first fun firstFun() { - sec + s } // EXIST: secondFun \ No newline at end of file diff --git a/idea/testData/completion/basic/multifile/TopLevelFunction-2.kt b/idea/testData/completion/basic/multifile/TopLevelFunction-2.kt index 2617299e37e..0201ce312ee 100644 --- a/idea/testData/completion/basic/multifile/TopLevelFunction-2.kt +++ b/idea/testData/completion/basic/multifile/TopLevelFunction-2.kt @@ -1,4 +1,4 @@ -package second +package first fun secondFun() { } \ No newline at end of file From 5440738ce4b784a82d6d6f7204734f7f4f48e5b3 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Mon, 13 Aug 2012 21:40:48 +0400 Subject: [PATCH 08/36] Remove context reassignment in BodyResolver --- .../src/org/jetbrains/jet/lang/resolve/BodyResolver.java | 5 ----- .../src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index 32ce7e4f36e..b0535d980b4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -135,11 +135,6 @@ public class BodyResolver { } } - public void resolveBodies(@NotNull BodiesResolveContext bodiesResolveContext) { - context = bodiesResolveContext; - resolveBodies(); - } - public void resolveBodies() { resolveBehaviorDeclarationBodies(context); controlFlowAnalyzer.process(context); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java index f188bc41dfb..744b1df4a88 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java @@ -139,7 +139,7 @@ public class TopDownAnalyzer { overloadResolver.process(); if (!topDownAnalysisParameters.isAnalyzingBootstrapLibrary()) { - bodyResolver.resolveBodies(context); + bodyResolver.resolveBodies(); } context.debug("Exit"); From a47257c9c50f57e0d95cfcffd95d9f860234b0e0 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Mon, 13 Aug 2012 21:58:51 +0400 Subject: [PATCH 09/36] Give receiver for chained scope in constructor --- .../jet/lang/resolve/lazy/LazyClassDescriptor.java | 3 ++- .../jet/lang/resolve/scopes/ChainedScope.java | 14 +++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java index 54f566ac2d2..17b0f7e4865 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java @@ -148,7 +148,8 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes scope.addLabeledDeclaration(this); scope.changeLockLevel(WritableScope.LockLevel.READING); - scopeForMemberDeclarationResolution = new ChainedScope(this, scope, getScopeForMemberLookup(), getScopeForClassHeaderResolution()); + scopeForMemberDeclarationResolution = new ChainedScope(this, getScopeForMemberLookup().getImplicitReceiver(), + scope, getScopeForMemberLookup(), getScopeForClassHeaderResolution()); } return scopeForMemberDeclarationResolution; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java index 0accb3f1418..df9a9973f70 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java @@ -33,11 +33,17 @@ import java.util.Set; */ public class ChainedScope implements JetScope { private final DeclarationDescriptor containingDeclaration; + private final ReceiverDescriptor implicitReceiver; private final JetScope[] scopeChain; private Collection allDescriptors; public ChainedScope(DeclarationDescriptor containingDeclaration, JetScope... scopes) { + this(containingDeclaration, ReceiverDescriptor.NO_RECEIVER, scopes); + } + + public ChainedScope(DeclarationDescriptor containingDeclaration, ReceiverDescriptor implicitReceiver, JetScope... scopes) { this.containingDeclaration = containingDeclaration; + this.implicitReceiver = implicitReceiver; scopeChain = scopes.clone(); } @@ -118,13 +124,7 @@ public class ChainedScope implements JetScope { @NotNull @Override public ReceiverDescriptor getImplicitReceiver() { - for (JetScope scope : scopeChain) { - if (scope.getImplicitReceiver() != ReceiverDescriptor.NO_RECEIVER) { - return scope.getImplicitReceiver(); - } - } - - return ReceiverDescriptor.NO_RECEIVER; + return implicitReceiver; } @Override From b5b72f93dcee807d45621e3a967a811aed56d234 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 14 Aug 2012 15:38:52 +0400 Subject: [PATCH 10/36] getTopLevelFunctionDescriptorsByName should give descriptors from the predefined resolve session --- .../jet/lang/psi/JetSimpleNameExpression.java | 1 + .../jet/plugin/caches/JetShortNamesCache.java | 39 ++++++++++++------- .../completion/JetCompletionContributor.java | 8 ++-- .../project/WholeProjectAnalyzerFacade.java | 7 +--- .../plugin/quickfix/ImportClassAndFunFix.java | 2 + 5 files changed, 35 insertions(+), 22 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.java index b47e6f295bf..d5e997aeee0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.java @@ -88,6 +88,7 @@ public class JetSimpleNameExpression extends JetReferenceExpression { return text != null ? JetPsiUtil.unquoteIdentifierOrFieldReference(text) : null; } + @Nullable public Name getReferencedNameAsName() { String name = getReferencedName(); if (name != null && name.length() == 0) { diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java index 5116f5d5dee..997f9f094c1 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java @@ -21,10 +21,7 @@ import com.google.common.collect.Collections2; import com.google.common.collect.Sets; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiField; -import com.intellij.psi.PsiMethod; +import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.PsiShortNamesCache; import com.intellij.util.ArrayUtil; @@ -34,17 +31,16 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.asJava.JavaElementFinder; -import org.jetbrains.jet.lang.descriptors.CallableDescriptor; -import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTraceContext; import org.jetbrains.jet.lang.resolve.ImportPath; import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver; +import org.jetbrains.jet.lang.resolve.lazy.LazyBindingContextUtils; import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils; @@ -158,13 +154,13 @@ public class JetShortNamesCache extends PsiShortNamesCache { public Collection getTopLevelFunctionDescriptorsByName( @NotNull String name, @NotNull JetSimpleNameExpression expression, + @NotNull ResolveSession resolveSession, @NotNull GlobalSearchScope scope ) { - JetFile jetFile = (JetFile) expression.getContainingFile(); - BindingContext context = WholeProjectAnalyzerFacade.getLazyResolveContext(jetFile, expression); + BindingContext context = LazyBindingContextUtils.getExpressionBindingContext(resolveSession, expression); JetScope jetScope = context.get(BindingContext.RESOLUTION_SCOPE, expression); - if (jetScope == null) { + if (jetScope == null || name.isEmpty()) { return Collections.emptyList(); } @@ -185,11 +181,26 @@ public class JetShortNamesCache extends PsiShortNamesCache { } } + Set affectedPackages = Sets.newHashSet(); Collection jetNamedFunctions = JetShortFunctionNameIndex.getInstance().get(name, project, scope); for (JetNamedFunction jetNamedFunction : jetNamedFunctions) { - ResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile)jetNamedFunction.getContainingFile()); - FunctionDescriptor functionDescriptor = (FunctionDescriptor) resolveSession.resolveToDescriptor(jetNamedFunction); - result.add(functionDescriptor); + PsiFile containingFile = jetNamedFunction.getContainingFile(); + if (containingFile instanceof JetFile) { + JetFile jetFile = (JetFile) containingFile; + String packageName = jetFile.getPackageName(); + if (packageName != null) { + affectedPackages.add(new FqName(packageName)); + } + } + } + + Name referenceName = Name.identifier(name); + + for (FqName affectedPackage : affectedPackages) { + NamespaceDescriptor packageDescriptor = resolveSession.getPackageDescriptorByFqName(affectedPackage); + assert packageDescriptor != null : "There's a function in stub index with invalid package"; + JetScope memberScope = packageDescriptor.getMemberScope(); + result.addAll(memberScope.getFunctions(referenceName)); } return result; diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java index e1f0cf5d72c..6653bd1fd18 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java @@ -35,6 +35,8 @@ import org.jetbrains.jet.cli.jvm.compiler.TipsManager; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.lazy.LazyBindingContextUtils; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.plugin.caches.JetCacheManager; @@ -202,12 +204,12 @@ public class JetCompletionContributor extends CompletionContributor { GlobalSearchScope scope = GlobalSearchScope.allScope(project); Collection functionNames = namesCache.getAllTopLevelFunctionNames(); - BindingContext resolutionContext = WholeProjectAnalyzerFacade.getLazyResolveContext( - (JetFile) position.getContainingFile(), expression); + ResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) position.getContainingFile()); + BindingContext resolutionContext = LazyBindingContextUtils.getExpressionBindingContext(resolveSession, expression); for (String name : functionNames) { if (name.contains(actualPrefix)) { - for (FunctionDescriptor function : namesCache.getTopLevelFunctionDescriptorsByName(name, expression, scope)) { + for (FunctionDescriptor function : namesCache.getTopLevelFunctionDescriptorsByName(name, expression, resolveSession, scope)) { addCompletionToResult(result, DescriptorLookupConverter.createLookupElement(resolutionContext, function), session); } } diff --git a/idea/src/org/jetbrains/jet/plugin/project/WholeProjectAnalyzerFacade.java b/idea/src/org/jetbrains/jet/plugin/project/WholeProjectAnalyzerFacade.java index 51b1c6035bc..c6365a15818 100644 --- a/idea/src/org/jetbrains/jet/plugin/project/WholeProjectAnalyzerFacade.java +++ b/idea/src/org/jetbrains/jet/plugin/project/WholeProjectAnalyzerFacade.java @@ -26,9 +26,6 @@ import org.jetbrains.jet.lang.resolve.java.JetFilesProvider; import org.jetbrains.jet.lang.resolve.lazy.LazyBindingContextUtils; import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; -import static org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache.analyzeFileWithCache; -import static org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache.getLazyResolveSession; - /** * @author abreslav */ @@ -39,12 +36,12 @@ public final class WholeProjectAnalyzerFacade { @NotNull public static AnalyzeExhaust analyzeProjectWithCacheOnAFile(@NotNull JetFile file) { - return analyzeFileWithCache(file, JetFilesProvider.getInstance(file.getProject()).sampleToAllFilesInModule()); + return AnalyzerFacadeWithCache.analyzeFileWithCache(file, JetFilesProvider.getInstance(file.getProject()).sampleToAllFilesInModule()); } @NotNull public static ResolveSession getLazyResolveSessionForFile(@NotNull JetFile file) { - return getLazyResolveSession(file); + return AnalyzerFacadeWithCache.getLazyResolveSession(file); } @NotNull diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java index a705df0789a..01bb8193002 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java @@ -110,9 +110,11 @@ public class ImportClassAndFunFix extends JetHintAction JetSimpleNameExpression expression, @NotNull Project project) { JetShortNamesCache namesCache = JetCacheManager.getInstance(project).getNamesCache(); + Collection topLevelFunctions = namesCache.getTopLevelFunctionDescriptorsByName( referenceName, expression, + WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) expression.getContainingFile()), GlobalSearchScope.allScope(project)); return Sets.newHashSet(Collections2.transform(topLevelFunctions, new Function() { From b722e85c2b56951eef1eabf5a71010d31a1710c3 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 14 Aug 2012 16:19:41 +0400 Subject: [PATCH 11/36] Propagate lazy resolve session to getJetCallableExtensions() --- .../jet/plugin/caches/JetShortNamesCache.java | 5 +- .../completion/JetCompletionContributor.java | 58 +++++++++++-------- .../plugin/quickfix/ImportClassAndFunFix.java | 23 +++++--- 3 files changed, 49 insertions(+), 37 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java index 997f9f094c1..d27db8e10ad 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java @@ -234,13 +234,12 @@ public class JetShortNamesCache extends PsiShortNamesCache { public Collection getJetCallableExtensions( @NotNull Condition acceptedNameCondition, @NotNull JetSimpleNameExpression expression, + @NotNull ResolveSession resolveSession, @NotNull GlobalSearchScope searchScope ) { Collection resultDescriptors = new ArrayList(); - JetFile jetFile = (JetFile) expression.getContainingFile(); - - BindingContext context = WholeProjectAnalyzerFacade.getLazyResolveContext(jetFile, expression); + BindingContext context = LazyBindingContextUtils.getExpressionBindingContext(resolveSession, expression); JetExpression receiverExpression = expression.getReceiverExpression(); if (receiverExpression != null) { diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java index 6653bd1fd18..a193571eee3 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java @@ -55,6 +55,8 @@ public class JetCompletionContributor extends CompletionContributor { private static class CompletionSession { public boolean isSomethingAdded = false; public int customInvocationCount = 0; + public ResolveSession resolveSession = null; + public BindingContext expressionBindingContext = null; @Nullable public DeclarationDescriptor inDescriptor = null; @@ -79,18 +81,25 @@ public class JetCompletionContributor extends CompletionContributor { JetSimpleNameReference jetReference = getJetReference(parameters); if (jetReference != null) { - BindingContext jetContext = WholeProjectAnalyzerFacade.getLazyResolveContext( - (JetFile) position.getContainingFile(), jetReference.getExpression()); + session.resolveSession = + WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) position.getContainingFile()); - JetScope scope = jetContext.get(BindingContext.RESOLUTION_SCOPE, jetReference.getExpression()); + session.expressionBindingContext = LazyBindingContextUtils.getExpressionBindingContext( + session.resolveSession, jetReference.getExpression()); + + JetScope scope = session.expressionBindingContext.get(BindingContext.RESOLUTION_SCOPE, jetReference.getExpression()); session.inDescriptor = scope != null ? scope.getContainingDeclaration() : null; - completeForReference(parameters, result, position, jetReference, session, jetContext); + completeForReference(parameters, result, position, jetReference, session); if (!session.isSomethingAdded && session.customInvocationCount == 0) { // Rerun completion if nothing was found session.customInvocationCount = 1; - completeForReference(parameters, result, position, jetReference, session, jetContext); + session.resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) position.getContainingFile()); + session.expressionBindingContext = LazyBindingContextUtils.getExpressionBindingContext( + session.resolveSession, jetReference.getExpression()); + + completeForReference(parameters, result, position, jetReference, session); } } @@ -105,18 +114,17 @@ public class JetCompletionContributor extends CompletionContributor { @NotNull CompletionResultSet result, @NotNull PsiElement position, @NotNull JetSimpleNameReference jetReference, - @NotNull CompletionSession session, - BindingContext jetContext) { + @NotNull CompletionSession session) { if (isOnlyKeywordCompletion(position)) { return; } if (shouldRunTypeCompletionOnly(position, jetReference)) { if (session.customInvocationCount > 0) { - addClasses(parameters, result, session, jetContext); + addClasses(parameters, result, session); } else { - for (LookupElement variant : getReferenceVariants(jetReference, result, session, jetContext)) { + for (LookupElement variant : getReferenceVariants(jetReference, result, session)) { if (isTypeDeclaration(variant)) { addCheckedCompletionToResult(result, variant, session); } @@ -126,7 +134,7 @@ public class JetCompletionContributor extends CompletionContributor { return; } - for (LookupElement variant : getReferenceVariants(jetReference, result, session, jetContext)) { + for (LookupElement variant : getReferenceVariants(jetReference, result, session)) { addCheckedCompletionToResult(result, variant, session); } @@ -144,12 +152,12 @@ public class JetCompletionContributor extends CompletionContributor { } if (shouldRunTopLevelCompletion(parameters, session)) { - addClasses(parameters, result, session, jetContext); + addClasses(parameters, result, session); addJetTopLevelFunctions(jetReference.getExpression(), result, position, session); } if (shouldRunExtensionsCompletion(parameters, prefix, session)) { - addJetExtensions(jetReference.getExpression(), result, position); + addJetExtensions(jetReference.getExpression(), result, position, session); } } @@ -157,7 +165,12 @@ public class JetCompletionContributor extends CompletionContributor { return PsiTreeUtil.getParentOfType(position, JetModifierList.class) != null; } - private static void addJetExtensions(@NotNull JetSimpleNameExpression expression, @NotNull CompletionResultSet result, @NotNull PsiElement position) { + private static void addJetExtensions( + @NotNull JetSimpleNameExpression expression, + @NotNull CompletionResultSet result, + @NotNull PsiElement position, + @NotNull CompletionSession session + ) { final PrefixMatcher prefixMatcher = result.getPrefixMatcher(); JetShortNamesCache namesCache = JetCacheManager.getInstance(position.getProject()).getNamesCache(); Condition matchPrefixCondition = new Condition() { @@ -168,13 +181,10 @@ public class JetCompletionContributor extends CompletionContributor { }; Collection jetCallableExtensions = namesCache.getJetCallableExtensions( - matchPrefixCondition, expression, GlobalSearchScope.allScope(position.getProject())); - - BindingContext context = WholeProjectAnalyzerFacade.getLazyResolveContext( - (JetFile) position.getContainingFile(), expression); + matchPrefixCondition, expression, session.resolveSession, GlobalSearchScope.allScope(position.getProject())); for (DeclarationDescriptor jetCallableExtension : jetCallableExtensions) { - result.addElement(DescriptorLookupConverter.createLookupElement(context, jetCallableExtension)); + result.addElement(DescriptorLookupConverter.createLookupElement(session.expressionBindingContext, jetCallableExtension)); } } @@ -222,9 +232,8 @@ public class JetCompletionContributor extends CompletionContributor { private static void addClasses( @NotNull CompletionParameters parameters, @NotNull final CompletionResultSet result, - @NotNull final CompletionSession session, - BindingContext jetContext) { - JetClassCompletionContributor.addClasses(parameters, result, jetContext, new Consumer() { + @NotNull final CompletionSession session) { + JetClassCompletionContributor.addClasses(parameters, result, session.expressionBindingContext, new Consumer() { @Override public void consume(@NotNull LookupElement element) { addCompletionToResult(result, element, session); @@ -342,10 +351,9 @@ public class JetCompletionContributor extends CompletionContributor { private static LookupElement[] getReferenceVariants( @NotNull JetSimpleNameReference reference, @NotNull final CompletionResultSet result, - @NotNull final CompletionSession session, - BindingContext jetContext + @NotNull final CompletionSession session ) { - Collection descriptors = TipsManager.getReferenceVariants(reference.getExpression(), jetContext); + Collection descriptors = TipsManager.getReferenceVariants(reference.getExpression(), session.expressionBindingContext); Collection checkedDescriptors = Collections2.filter(descriptors, new Predicate() { @Override @@ -358,6 +366,6 @@ public class JetCompletionContributor extends CompletionContributor { } }); - return DescriptorLookupConverter.collectLookupElements(jetContext, checkedDescriptors); + return DescriptorLookupConverter.collectLookupElements(session.expressionBindingContext, checkedDescriptors); } } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java index 01bb8193002..d2d12e4fb97 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java @@ -50,6 +50,7 @@ import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.ImportPath; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.actions.JetAddImportAction; @@ -92,10 +93,12 @@ public class ImportClassAndFunFix extends JetHintAction assert referenceName != null; + ResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) element.getContainingFile()); + List result = Lists.newArrayList(); result.addAll(getClassNames(referenceName, (JetFile) file)); - result.addAll(getJetTopLevelFunctions(referenceName, element, file.getProject())); - result.addAll(getJetExtensionFunctions(referenceName, element, file.getProject())); + result.addAll(getJetTopLevelFunctions(referenceName, element, resolveSession, file.getProject())); + result.addAll(getJetExtensionFunctions(referenceName, element, resolveSession, file.getProject())); return Collections2.filter(result, new Predicate() { @Override @@ -106,16 +109,16 @@ public class ImportClassAndFunFix extends JetHintAction }); } - private static Collection getJetTopLevelFunctions(@NotNull String referenceName, - JetSimpleNameExpression expression, - @NotNull Project project) { + private static Collection getJetTopLevelFunctions( + @NotNull String referenceName, + @NotNull JetSimpleNameExpression expression, + @NotNull ResolveSession resolveSession, + @NotNull Project project + ) { JetShortNamesCache namesCache = JetCacheManager.getInstance(project).getNamesCache(); Collection topLevelFunctions = namesCache.getTopLevelFunctionDescriptorsByName( - referenceName, - expression, - WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) expression.getContainingFile()), - GlobalSearchScope.allScope(project)); + referenceName, expression, resolveSession, GlobalSearchScope.allScope(project)); return Sets.newHashSet(Collections2.transform(topLevelFunctions, new Function() { @Override @@ -129,6 +132,7 @@ public class ImportClassAndFunFix extends JetHintAction private static Collection getJetExtensionFunctions( @NotNull final String referenceName, @NotNull JetSimpleNameExpression expression, + @NotNull ResolveSession resolveSession, @NotNull Project project ) { JetShortNamesCache namesCache = JetCacheManager.getInstance(project).getNamesCache(); @@ -140,6 +144,7 @@ public class ImportClassAndFunFix extends JetHintAction } }, expression, + resolveSession, GlobalSearchScope.allScope(project)); return Sets.newHashSet(Collections2.transform(jetCallableExtensions, new Function() { From 8f5811fce2d7b6fb0bc3ba75e627fbec338bc3d1 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 14 Aug 2012 19:30:23 +0400 Subject: [PATCH 12/36] Propagate lazy resolve session to getJetClassesDescriptors() --- ...extUtils.java => ResolveSessionUtils.java} | 74 +++++++++++++++++-- .../jet/plugin/caches/JetShortNamesCache.java | 15 ++-- .../JetClassCompletionContributor.java | 29 ++++---- .../completion/JetCompletionContributor.java | 12 +-- .../JetExtensionReceiverTypeContributor.java | 12 +-- .../project/WholeProjectAnalyzerFacade.java | 4 +- .../plugin/quickfix/ImportClassAndFunFix.java | 12 +-- 7 files changed, 111 insertions(+), 47 deletions(-) rename compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/{LazyBindingContextUtils.java => ResolveSessionUtils.java} (75%) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyBindingContextUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSessionUtils.java similarity index 75% rename from compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyBindingContextUtils.java rename to compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSessionUtils.java index 654b936eb06..9e46b39a7b3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyBindingContextUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSessionUtils.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang.resolve.lazy; import com.google.common.base.Predicates; +import com.google.common.collect.Lists; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -27,20 +28,20 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; +import org.jetbrains.jet.util.QualifiedNamesUtil; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; +import java.util.*; /** * @author Nikolay Krasko */ -public class LazyBindingContextUtils { - private static final Logger LOG = Logger.getInstance("#" + LazyBindingContextUtils.class.getName()); +public class ResolveSessionUtils { + private static final Logger LOG = Logger.getInstance("#" + ResolveSessionUtils.class.getName()); - private LazyBindingContextUtils() { + private ResolveSessionUtils() { } private static class EmptyBodyResolveContext implements BodiesResolveContext { @@ -198,4 +199,65 @@ public class LazyBindingContextUtils { return null; } + + public static Collection getClassDescriptorsByFqName(@NotNull ResolveSession resolveSession, @NotNull FqName fqName) { + if (fqName.isRoot()) { + return Collections.emptyList(); + } + + Collection classDescriptors = Lists.newArrayList(); + + FqName packageFqName = fqName.parent(); + while (true) { + NamespaceDescriptor packageDescriptor = resolveSession.getPackageDescriptorByFqName(packageFqName); + if (packageDescriptor != null) { + FqName classInPackagePath = new FqName(QualifiedNamesUtil.tail(packageFqName, fqName)); + Collection descriptors = getClassDescriptorsByFqName(packageDescriptor, classInPackagePath); + classDescriptors.addAll(descriptors); + } + + if (packageFqName.isRoot()) { + break; + } + else { + packageFqName = packageFqName.parent(); + } + } + + return classDescriptors; + } + + private static Collection getClassDescriptorsByFqName(NamespaceDescriptor packageDescriptor, FqName path) { + if (path.isRoot()) { + return Collections.emptyList(); + } + + Collection scopes = Arrays.asList(packageDescriptor.getMemberScope()); + + List names = path.pathSegments(); + if (names.size() > 1) { + for (Name subName : path.pathSegments().subList(0, names.size() - 1)) { + Collection tempScopes = Lists.newArrayList(); + for (JetScope scope : scopes) { + ClassifierDescriptor classifier = scope.getClassifier(subName); + if (classifier instanceof ClassDescriptorBase) { + ClassDescriptorBase classDescriptor = (ClassDescriptorBase) classifier; + tempScopes.add(classDescriptor.getUnsubstitutedInnerClassesScope()); + } + } + scopes = tempScopes; + } + } + + Name shortName = path.shortName(); + Collection resultClassDescriptors = Lists.newArrayList(); + for (JetScope scope : scopes) { + ClassifierDescriptor classifier = scope.getClassifier(shortName); + if (classifier instanceof ClassDescriptor) { + resultClassDescriptors.add((ClassDescriptor) classifier); + } + } + + return resultClassDescriptors; + } } diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java index d27db8e10ad..a4b4d972529 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java @@ -37,7 +37,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTraceContext; import org.jetbrains.jet.lang.resolve.ImportPath; import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver; -import org.jetbrains.jet.lang.resolve.lazy.LazyBindingContextUtils; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils; import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; @@ -46,7 +46,6 @@ import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils; import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; -import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; import org.jetbrains.jet.plugin.stubindex.JetExtensionFunctionNameIndex; import org.jetbrains.jet.plugin.stubindex.JetFullClassNameIndex; import org.jetbrains.jet.plugin.stubindex.JetShortClassNameIndex; @@ -157,7 +156,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { @NotNull ResolveSession resolveSession, @NotNull GlobalSearchScope scope ) { - BindingContext context = LazyBindingContextUtils.getExpressionBindingContext(resolveSession, expression); + BindingContext context = ResolveSessionUtils.getExpressionBindingContext(resolveSession, expression); JetScope jetScope = context.get(BindingContext.RESOLUTION_SCOPE, expression); if (jetScope == null || name.isEmpty()) { @@ -239,7 +238,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { ) { Collection resultDescriptors = new ArrayList(); - BindingContext context = LazyBindingContextUtils.getExpressionBindingContext(resolveSession, expression); + BindingContext context = ResolveSessionUtils.getExpressionBindingContext(resolveSession, expression); JetExpression receiverExpression = expression.getReceiverExpression(); if (receiverExpression != null) { @@ -286,18 +285,14 @@ public class JetShortNamesCache extends PsiShortNamesCache { public Collection getJetClassesDescriptors( @NotNull Condition acceptedShortNameCondition, - @NotNull JetFile jetFile + @NotNull ResolveSession resolveSession ) { - BindingContext context = WholeProjectAnalyzerFacade.getLazyResolveContext(jetFile, null); Collection classDescriptors = new ArrayList(); for (String fqName : JetFullClassNameIndex.getInstance().getAllKeys(project)) { FqName classFQName = new FqName(fqName); if (acceptedShortNameCondition.value(classFQName.shortName().getName())) { - ClassDescriptor descriptor = context.get(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, classFQName); - if (descriptor != null) { - classDescriptors.add(descriptor); - } + classDescriptors.addAll(ResolveSessionUtils.getClassDescriptorsByFqName(resolveSession, classFQName)); } } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetClassCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetClassCompletionContributor.java index 561aad3ebf3..29fe370a5fc 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetClassCompletionContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetClassCompletionContributor.java @@ -21,7 +21,6 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiFile; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.Consumer; import org.jetbrains.annotations.NotNull; @@ -32,11 +31,11 @@ import org.jetbrains.jet.lang.psi.JetClassOrObject; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils; import org.jetbrains.jet.plugin.caches.JetCacheManager; import org.jetbrains.jet.plugin.caches.JetShortNamesCache; import org.jetbrains.jet.plugin.completion.handlers.JetJavaClassInsertHandler; import org.jetbrains.jet.plugin.project.JsModuleDetector; -import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; import org.jetbrains.jet.plugin.stubindex.JetFullClassNameIndex; import java.util.Collection; @@ -54,6 +53,7 @@ public class JetClassCompletionContributor extends CompletionContributor { @NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result, @NotNull final BindingContext jetContext, + @NotNull final ResolveSession resolveSession, @NotNull final Consumer consumer ) { CompletionResultSet tempResult = result.withPrefixMatcher(CompletionUtil.findReferenceOrAlphanumericPrefix(parameters)); @@ -75,7 +75,7 @@ public class JetClassCompletionContributor extends CompletionContributor { JavaPsiClassReferenceElement javaPsiReferenceElement = (JavaPsiClassReferenceElement) lookupElement; PsiClass psiClass = javaPsiReferenceElement.getObject(); - if (addAsJetLookupElement(parameters, psiClass, consumer)) { + if (addAsJetLookupElement(parameters, psiClass, resolveSession, jetContext, consumer)) { return; } @@ -95,8 +95,7 @@ public class JetClassCompletionContributor extends CompletionContributor { public boolean value(String shortName) { return result.getPrefixMatcher().prefixMatches(shortName); } - }, - (JetFile) parameters.getOriginalFile()); + }, resolveSession); for (ClassDescriptor descriptor : descriptors) { consumer.consume(DescriptorLookupConverter.createLookupElement(jetContext, descriptor)); @@ -104,23 +103,27 @@ public class JetClassCompletionContributor extends CompletionContributor { } } - private static boolean addAsJetLookupElement(CompletionParameters parameters, PsiClass aClass, Consumer consumer) { + private static boolean addAsJetLookupElement( + CompletionParameters parameters, + PsiClass aClass, + ResolveSession resolveSession, + BindingContext context, + Consumer consumer + ) { if (aClass instanceof JetLightClass) { Project project = parameters.getPosition().getProject(); - PsiFile completionFile = parameters.getPosition().getContainingFile(); Collection classOrObjects = JetFullClassNameIndex.getInstance().get(aClass.getQualifiedName(), project, GlobalSearchScope.allScope(project)); for (JetClassOrObject classOrObject : classOrObjects) { if (classOrObject.getContainingFile().getOriginalFile().equals(aClass.getContainingFile())) { - PsiFile fileOfClass = completionFile.getOriginalFile().equals(aClass.getContainingFile()) ? completionFile : aClass.getContainingFile(); + Collection classDescriptors = ResolveSessionUtils.getClassDescriptorsByFqName( + resolveSession,((JetLightClass) aClass).getFqName()); + for (ClassDescriptor descriptor : classDescriptors) { + consumer.consume(DescriptorLookupConverter.createLookupElement(context, descriptor)); + } - ResolveSession resolveSessionForFile = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) fileOfClass); - ClassDescriptor descriptor = resolveSessionForFile.getClassDescriptor(classOrObject); - - LookupElement element = DescriptorLookupConverter.createLookupElement(resolveSessionForFile.getBindingContext(), descriptor); - consumer.consume(element); return true; } } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java index a193571eee3..6a5c014aa03 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java @@ -35,7 +35,7 @@ import org.jetbrains.jet.cli.jvm.compiler.TipsManager; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.resolve.lazy.LazyBindingContextUtils; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils; import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lexer.JetTokens; @@ -84,7 +84,7 @@ public class JetCompletionContributor extends CompletionContributor { session.resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) position.getContainingFile()); - session.expressionBindingContext = LazyBindingContextUtils.getExpressionBindingContext( + session.expressionBindingContext = ResolveSessionUtils.getExpressionBindingContext( session.resolveSession, jetReference.getExpression()); JetScope scope = session.expressionBindingContext.get(BindingContext.RESOLUTION_SCOPE, jetReference.getExpression()); @@ -96,7 +96,7 @@ public class JetCompletionContributor extends CompletionContributor { // Rerun completion if nothing was found session.customInvocationCount = 1; session.resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) position.getContainingFile()); - session.expressionBindingContext = LazyBindingContextUtils.getExpressionBindingContext( + session.expressionBindingContext = ResolveSessionUtils.getExpressionBindingContext( session.resolveSession, jetReference.getExpression()); completeForReference(parameters, result, position, jetReference, session); @@ -215,7 +215,7 @@ public class JetCompletionContributor extends CompletionContributor { Collection functionNames = namesCache.getAllTopLevelFunctionNames(); ResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) position.getContainingFile()); - BindingContext resolutionContext = LazyBindingContextUtils.getExpressionBindingContext(resolveSession, expression); + BindingContext resolutionContext = ResolveSessionUtils.getExpressionBindingContext(resolveSession, expression); for (String name : functionNames) { if (name.contains(actualPrefix)) { @@ -233,7 +233,9 @@ public class JetCompletionContributor extends CompletionContributor { @NotNull CompletionParameters parameters, @NotNull final CompletionResultSet result, @NotNull final CompletionSession session) { - JetClassCompletionContributor.addClasses(parameters, result, session.expressionBindingContext, new Consumer() { + JetClassCompletionContributor.addClasses( + parameters, result, + session.expressionBindingContext, session.resolveSession, new Consumer() { @Override public void consume(@NotNull LookupElement element) { addCompletionToResult(result, element, session); diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetExtensionReceiverTypeContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetExtensionReceiverTypeContributor.java index 7d7b92482b5..f1e818ecb78 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetExtensionReceiverTypeContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetExtensionReceiverTypeContributor.java @@ -25,7 +25,7 @@ import com.intellij.util.Consumer; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.JetFile; -import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; @@ -41,11 +41,13 @@ public class JetExtensionReceiverTypeContributor extends CompletionContributor { ProcessingContext context, final @NotNull CompletionResultSet result ) { - BindingContext jetContext = WholeProjectAnalyzerFacade - .getLazyResolveContext((JetFile) parameters.getPosition().getContainingFile(), null); + ResolveSession resolveSession = + WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) parameters.getPosition().getContainingFile()); - if (parameters.getInvocationCount() > 0 || parameters.getCompletionType() == CompletionType.CLASS_NAME) { - JetClassCompletionContributor.addClasses(parameters, result, jetContext, new Consumer() { + if (parameters.getInvocationCount() > 0) { + JetClassCompletionContributor.addClasses( + parameters, result, + resolveSession.getBindingContext(), resolveSession, new Consumer() { @Override public void consume(@NotNull LookupElement element) { result.addElement(element); diff --git a/idea/src/org/jetbrains/jet/plugin/project/WholeProjectAnalyzerFacade.java b/idea/src/org/jetbrains/jet/plugin/project/WholeProjectAnalyzerFacade.java index c6365a15818..aa28a0aa878 100644 --- a/idea/src/org/jetbrains/jet/plugin/project/WholeProjectAnalyzerFacade.java +++ b/idea/src/org/jetbrains/jet/plugin/project/WholeProjectAnalyzerFacade.java @@ -23,7 +23,7 @@ import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.java.JetFilesProvider; -import org.jetbrains.jet.lang.resolve.lazy.LazyBindingContextUtils; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils; import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; /** @@ -48,7 +48,7 @@ public final class WholeProjectAnalyzerFacade { public static BindingContext getLazyResolveContext(@NotNull JetFile file, @Nullable JetExpression expression) { ResolveSession resolveSession = getLazyResolveSessionForFile(file); return expression != null ? - LazyBindingContextUtils.getExpressionBindingContext(resolveSession, expression) : + ResolveSessionUtils.getExpressionBindingContext(resolveSession, expression) : resolveSession.getBindingContext(); } } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java index d2d12e4fb97..28cab114b38 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassAndFunFix.java @@ -96,7 +96,7 @@ public class ImportClassAndFunFix extends JetHintAction ResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) element.getContainingFile()); List result = Lists.newArrayList(); - result.addAll(getClassNames(referenceName, (JetFile) file)); + result.addAll(getClassNames(referenceName, (JetFile) file, resolveSession)); result.addAll(getJetTopLevelFunctions(referenceName, element, resolveSession, file.getProject())); result.addAll(getJetExtensionFunctions(referenceName, element, resolveSession, file.getProject())); @@ -159,14 +159,14 @@ public class ImportClassAndFunFix extends JetHintAction /* * Searches for possible class names in kotlin context and java facade. */ - public static Collection getClassNames(@NotNull String referenceName, @NotNull JetFile file) { + public static Collection getClassNames(@NotNull String referenceName, @NotNull JetFile file, @NotNull ResolveSession resolveSession) { Set possibleResolveNames = Sets.newHashSet(); if (!JsModuleDetector.isJsModule(file)) { possibleResolveNames.addAll(getClassesFromCache(referenceName, file)); } else { - possibleResolveNames.addAll(getJetClasses(referenceName, file)); + possibleResolveNames.addAll(getJetClasses(referenceName, file.getProject(), resolveSession)); } // TODO: Do appropriate sorting @@ -198,14 +198,14 @@ public class ImportClassAndFunFix extends JetHintAction }); } - private static Collection getJetClasses(@NotNull final String typeName, @NotNull JetFile file) { - JetShortNamesCache cache = JetCacheManager.getInstance(file.getProject()).getNamesCache(); + private static Collection getJetClasses(@NotNull final String typeName, @NotNull Project project, @NotNull ResolveSession resolveSession) { + JetShortNamesCache cache = JetCacheManager.getInstance(project).getNamesCache(); Collection descriptors = cache.getJetClassesDescriptors(new Condition() { @Override public boolean value(String s) { return typeName.equals(s); } - }, file); + }, resolveSession); return Collections2.transform(descriptors, new Function() { @Override From 84a6c63d071b7feb6cd22e4762072d316e1943a3 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 14 Aug 2012 19:31:21 +0400 Subject: [PATCH 13/36] Remove some unused methods from QualifiedNamesUtil --- .../jetbrains/jet/util/QualifiedNamesUtil.java | 15 --------------- .../org/jetbrains/jet/asJava/JetLightClass.java | 3 +-- .../caches/JetFromJavaDescriptorHelper.java | 2 +- 3 files changed, 2 insertions(+), 18 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/util/QualifiedNamesUtil.java b/compiler/frontend/src/org/jetbrains/jet/util/QualifiedNamesUtil.java index 7c4e6d4afef..59e2e7e1133 100644 --- a/compiler/frontend/src/org/jetbrains/jet/util/QualifiedNamesUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/util/QualifiedNamesUtil.java @@ -37,11 +37,6 @@ public final class QualifiedNamesUtil { (subpackageName.getFqName().startsWith(packageName.getFqName()) && subpackageName.getFqName().charAt(packageName.getFqName().length()) == '.'); } - public static boolean isShortNameForFQN(@NotNull final String name, @NotNull final FqName fqn) { - return fqn.getFqName().equals(name) || - (fqn.getFqName().endsWith(name) && fqn.getFqName().charAt(fqn.getFqName().length() - name.length() - 1) == '.'); - } - public static boolean isOneSegmentFQN(@NotNull final String fqn) { if (fqn.isEmpty()) { return false; @@ -54,16 +49,6 @@ public final class QualifiedNamesUtil { return isOneSegmentFQN(fqn.getFqName()); } - @NotNull - public static Name fqnToShortName(@NotNull FqName fqn) { - return getLastSegment(fqn); - } - - @NotNull - public static Name getLastSegment(@NotNull FqName fqn) { - return fqn.shortName(); - } - @NotNull public static String getFirstSegment(@NotNull String fqn) { int dotIndex = fqn.indexOf('.'); diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java index 29418e20807..190b44759f0 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java @@ -51,7 +51,6 @@ import org.jetbrains.jet.lang.resolve.java.JetFilesProvider; import org.jetbrains.jet.lang.resolve.java.JetJavaMirrorMarker; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.plugin.JetLanguage; -import org.jetbrains.jet.util.QualifiedNamesUtil; import org.jetbrains.jet.utils.Progress; import javax.swing.*; @@ -74,7 +73,7 @@ public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMa @Override public String getName() { - return QualifiedNamesUtil.fqnToShortName(qualifiedName).getName(); + return qualifiedName.shortName().getName(); } @Override diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetFromJavaDescriptorHelper.java b/idea/src/org/jetbrains/jet/plugin/caches/JetFromJavaDescriptorHelper.java index a55d17ecb43..aaf94b2e1ba 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/JetFromJavaDescriptorHelper.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/JetFromJavaDescriptorHelper.java @@ -137,7 +137,7 @@ class JetFromJavaDescriptorHelper { FqName classFQN = new FqName(containingClass.getQualifiedName()); if (classFQN != null) { - if (QualifiedNamesUtil.fqnToShortName(classFQN).getName().equals(JvmAbi.PACKAGE_CLASS)) { + if (classFQN.shortName().toString().equals(JvmAbi.PACKAGE_CLASS)) { FqName classParentFQN = QualifiedNamesUtil.withoutLastSegment(classFQN); return QualifiedNamesUtil.combine(classParentFQN, Name.identifier(method.getName())); } From b1860641306ab153b4e42b795f559b401ee6eafa Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 14 Aug 2012 20:28:23 +0400 Subject: [PATCH 14/36] Use resolve session for checking comparability of descriptors --- .../completion/DescriptorLookupConverter.java | 31 ++++++++++++------- .../JetClassCompletionContributor.java | 6 ++-- .../completion/JetCompletionContributor.java | 14 ++++----- .../plugin/completion/JetLookupObject.java | 15 ++++++--- .../completion/JetPackagesContributor.java | 10 ++++-- .../references/JetSimpleNameReference.java | 9 +++--- 6 files changed, 51 insertions(+), 34 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java b/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java index dee80681d3d..bbc69f4f771 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java @@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.jetbrains.jet.plugin.JetDescriptorIconProvider; @@ -53,11 +54,11 @@ public final class DescriptorLookupConverter { private DescriptorLookupConverter() {} @NotNull - public static LookupElement createLookupElement(@NotNull BindingContext bindingContext, + public static LookupElement createLookupElement(@NotNull ResolveSession resolveSession, @NotNull DeclarationDescriptor descriptor, @Nullable PsiElement declaration) { LookupElementBuilder element = LookupElementBuilder.create( - new JetLookupObject(descriptor, bindingContext, declaration), descriptor.getName().getName()); + new JetLookupObject(descriptor, resolveSession, declaration), descriptor.getName().getName()); String presentableText = descriptor.getName().getName(); String typeText = ""; @@ -80,14 +81,14 @@ public final class DescriptorLookupConverter { // TODO: A special case when it's impossible to resolve type parameters from arguments. Need '<' caret '>' // TODO: Support omitting brackets for one argument functions if (functionDescriptor.getValueParameters().isEmpty()) { - element = element.setInsertHandler(EMPTY_FUNCTION_HANDLER); + element = element.withInsertHandler(EMPTY_FUNCTION_HANDLER); } else { if (functionDescriptor.getValueParameters().size() == 1 && JetStandardClasses.isFunctionType(functionDescriptor.getValueParameters().get(0).getType())) { - element = element.setInsertHandler(PARAMS_BRACES_FUNCTION_HANDLER); + element = element.withInsertHandler(PARAMS_BRACES_FUNCTION_HANDLER); } else { - element = element.setInsertHandler(PARAMS_PARENTHESIS_FUNCTION_HANDLER); + element = element.withInsertHandler(PARAMS_PARENTHESIS_FUNCTION_HANDLER); } } } @@ -100,20 +101,23 @@ public final class DescriptorLookupConverter { assert declaredIn != null; tailText = " (" + DescriptorUtils.getFQName(declaredIn) + ")"; tailTextGrayed = true; - element = element.setInsertHandler(JetClassInsertHandler.INSTANCE); + element = element.withInsertHandler(JetClassInsertHandler.INSTANCE); } else { typeText = DescriptorRenderer.TEXT.render(descriptor); } - element = element.setTailText(tailText, tailTextGrayed).setTypeText(typeText).setPresentableText(presentableText); - element = element.setIcon(JetDescriptorIconProvider.getIcon(descriptor, Iconable.ICON_FLAG_VISIBILITY)); + element = element.withTailText(tailText, tailTextGrayed).withTypeText(typeText).withPresentableText(presentableText); + element = element.withIcon(JetDescriptorIconProvider.getIcon(descriptor, Iconable.ICON_FLAG_VISIBILITY)); return element; } @NotNull - public static LookupElement createLookupElement(@NotNull BindingContext bindingContext, @NotNull DeclarationDescriptor descriptor) { + public static LookupElement createLookupElement( + @NotNull ResolveSession resolveSession, + @NotNull BindingContext bindingContext, + @NotNull DeclarationDescriptor descriptor) { if (descriptor instanceof CallableMemberDescriptor) { CallableMemberDescriptor callableMemberDescriptor = (CallableMemberDescriptor) descriptor; while (callableMemberDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { @@ -122,14 +126,17 @@ public final class DescriptorLookupConverter { } descriptor = callableMemberDescriptor; } - return createLookupElement(bindingContext, descriptor, BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor)); + return createLookupElement(resolveSession, descriptor, BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor)); } - public static LookupElement[] collectLookupElements(BindingContext bindingContext, Iterable descriptors) { + public static LookupElement[] collectLookupElements( + @NotNull ResolveSession resolveSession, + @NotNull BindingContext bindingContext, + @NotNull Iterable descriptors) { List result = Lists.newArrayList(); for (final DeclarationDescriptor descriptor : descriptors) { - result.add(createLookupElement(bindingContext, descriptor)); + result.add(createLookupElement(resolveSession, bindingContext, descriptor)); } return result.toArray(new LookupElement[result.size()]); diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetClassCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetClassCompletionContributor.java index 29fe370a5fc..8f4eca746bd 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetClassCompletionContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetClassCompletionContributor.java @@ -60,7 +60,7 @@ public class JetClassCompletionContributor extends CompletionContributor { final Collection jetOnlyClasses = JetShortNamesCache.getJetOnlyTypes(); for (DeclarationDescriptor jetOnlyClass : jetOnlyClasses) { - consumer.consume(DescriptorLookupConverter.createLookupElement(jetContext, jetOnlyClass)); + consumer.consume(DescriptorLookupConverter.createLookupElement(resolveSession, jetContext, jetOnlyClass)); } if (!JsModuleDetector.isJsModule((JetFile)parameters.getOriginalFile())) { @@ -98,7 +98,7 @@ public class JetClassCompletionContributor extends CompletionContributor { }, resolveSession); for (ClassDescriptor descriptor : descriptors) { - consumer.consume(DescriptorLookupConverter.createLookupElement(jetContext, descriptor)); + consumer.consume(DescriptorLookupConverter.createLookupElement(resolveSession, jetContext, descriptor)); } } } @@ -121,7 +121,7 @@ public class JetClassCompletionContributor extends CompletionContributor { Collection classDescriptors = ResolveSessionUtils.getClassDescriptorsByFqName( resolveSession,((JetLightClass) aClass).getFqName()); for (ClassDescriptor descriptor : classDescriptors) { - consumer.consume(DescriptorLookupConverter.createLookupElement(context, descriptor)); + consumer.consume(DescriptorLookupConverter.createLookupElement(resolveSession, context, descriptor)); } return true; diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java index 6a5c014aa03..e29431bccea 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java @@ -184,7 +184,8 @@ public class JetCompletionContributor extends CompletionContributor { matchPrefixCondition, expression, session.resolveSession, GlobalSearchScope.allScope(position.getProject())); for (DeclarationDescriptor jetCallableExtension : jetCallableExtensions) { - result.addElement(DescriptorLookupConverter.createLookupElement(session.expressionBindingContext, jetCallableExtension)); + result.addElement(DescriptorLookupConverter.createLookupElement( + session.resolveSession, session.expressionBindingContext, jetCallableExtension)); } } @@ -214,13 +215,11 @@ public class JetCompletionContributor extends CompletionContributor { GlobalSearchScope scope = GlobalSearchScope.allScope(project); Collection functionNames = namesCache.getAllTopLevelFunctionNames(); - ResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) position.getContainingFile()); - BindingContext resolutionContext = ResolveSessionUtils.getExpressionBindingContext(resolveSession, expression); - for (String name : functionNames) { if (name.contains(actualPrefix)) { - for (FunctionDescriptor function : namesCache.getTopLevelFunctionDescriptorsByName(name, expression, resolveSession, scope)) { - addCompletionToResult(result, DescriptorLookupConverter.createLookupElement(resolutionContext, function), session); + for (FunctionDescriptor function : namesCache.getTopLevelFunctionDescriptorsByName(name, expression, session.resolveSession, scope)) { + addCompletionToResult(result, DescriptorLookupConverter.createLookupElement( + session.resolveSession, session.expressionBindingContext, function), session); } } } @@ -342,6 +341,7 @@ public class JetCompletionContributor extends CompletionContributor { if (descriptor instanceof DeclarationDescriptorWithVisibility) { if (session.inDescriptor != null) { + //noinspection ConstantConditions return Visibilities.isVisible((DeclarationDescriptorWithVisibility)descriptor, session.inDescriptor); } } @@ -368,6 +368,6 @@ public class JetCompletionContributor extends CompletionContributor { } }); - return DescriptorLookupConverter.collectLookupElements(session.expressionBindingContext, checkedDescriptors); + return DescriptorLookupConverter.collectLookupElements(session.resolveSession, session.expressionBindingContext, checkedDescriptors); } } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetLookupObject.java b/idea/src/org/jetbrains/jet/plugin/completion/JetLookupObject.java index bb426044c8e..59ceaa59d5a 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetLookupObject.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetLookupObject.java @@ -16,11 +16,12 @@ package org.jetbrains.jet.plugin.completion; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.resolve.DescriptorRenderer; /** @@ -30,18 +31,20 @@ import org.jetbrains.jet.resolve.DescriptorRenderer; * @author Nikolay Krasko */ public final class JetLookupObject { + private static final Logger LOG = Logger.getInstance("#" + JetLookupObject.class.getName()); + @Nullable private final DeclarationDescriptor descriptor; @Nullable - private BindingContext context; + private ResolveSession resolveSession; @Nullable private final PsiElement psiElement; - public JetLookupObject(@Nullable DeclarationDescriptor descriptor, @NotNull BindingContext context, @Nullable PsiElement psiElement) { + public JetLookupObject(@Nullable DeclarationDescriptor descriptor, @NotNull ResolveSession resolveSession, @Nullable PsiElement psiElement) { this.descriptor = descriptor; - this.context = context; + this.resolveSession = resolveSession; this.psiElement = psiElement; } @@ -78,12 +81,14 @@ public final class JetLookupObject { // Same descriptor - same lookup element if (descriptor != null && other.descriptor != null) { - if (context == other.context) { + if (resolveSession == other.resolveSession) { if (descriptor.equals(other.descriptor)) { return true; } } else { + LOG.warn("Descriptors from different resolve sessions"); + String descriptorText = DescriptorRenderer.TEXT.render(descriptor); @SuppressWarnings("ConstantConditions") String otherDescriptorText = DescriptorRenderer.TEXT.render(other.descriptor); diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.java index 144c89ec9a0..64486a4491d 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.java @@ -28,6 +28,8 @@ import org.jetbrains.jet.cli.jvm.compiler.TipsManager; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetNamespaceHeader; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils; import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; import org.jetbrains.jet.plugin.references.JetSimpleNameReference; @@ -71,11 +73,13 @@ public class JetPackagesContributor extends CompletionContributor { int prefixLength = parameters.getOffset() - simpleNameReference.getExpression().getTextOffset(); result = result.withPrefixMatcher(new PlainPrefixMatcher(name.substring(0, prefixLength))); - BindingContext bindingContext = WholeProjectAnalyzerFacade.getLazyResolveContext( - (JetFile) namespaceHeader.getContainingFile(), simpleNameReference.getExpression()); + ResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile( + (JetFile) simpleNameReference.getExpression().getContainingFile()); + BindingContext bindingContext = ResolveSessionUtils.getExpressionBindingContext( + resolveSession, simpleNameReference.getExpression()); for (LookupElement variant : DescriptorLookupConverter.collectLookupElements( - bindingContext, TipsManager.getPackageReferenceVariants(simpleNameReference.getExpression(), bindingContext))) { + resolveSession, bindingContext, TipsManager.getPackageReferenceVariants(simpleNameReference.getExpression(), bindingContext))) { if (!variant.getLookupString().contains(DUMMY_IDENTIFIER)) { result.addElement(variant); } diff --git a/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java b/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java index 6be592e32e9..8e999bf912d 100644 --- a/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java +++ b/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java @@ -25,6 +25,8 @@ import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetPsiFactory; import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils; import org.jetbrains.jet.plugin.completion.DescriptorLookupConverter; import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; @@ -61,12 +63,11 @@ public class JetSimpleNameReference extends JetPsiReference { @NotNull @Override public Object[] getVariants() { - BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile( - (JetFile) myExpression.getContainingFile()) - .getBindingContext(); + ResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) getExpression().getContainingFile()); + BindingContext bindingContext = ResolveSessionUtils.getExpressionBindingContext(resolveSession, getExpression()); return DescriptorLookupConverter.collectLookupElements( - bindingContext, TipsManager.getReferenceVariants(myExpression, bindingContext)); + resolveSession, bindingContext, TipsManager.getReferenceVariants(myExpression, bindingContext)); } @Override From 199029360a5e7b030d5797053de567b87aa47328 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Tue, 14 Aug 2012 21:26:13 +0400 Subject: [PATCH 15/36] KT-2326 Link external annotations via mechanism in IDEA core when Kotlin depends on IDEA 12.x Dropped temporary classes. #KT-2326 fixed --- .../CoreExternalAnnotationsManager.java | 73 ++++ .../cli/jvm/compiler/JetCoreEnvironment.java | 12 +- .../resolve/java/JavaDescriptorResolver.java | 6 +- .../java/extAnnotations/ClassUtil.java | 203 ---------- .../CoreAnnotationsProvider.java | 316 --------------- .../ExternalAnnotationsProvider.java | 42 -- .../PsiExpressionTrimRenderer.java | 235 ------------ .../java/extAnnotations/PsiFormatUtil.java | 360 ------------------ .../extAnnotations/PsiFormatUtilBase.java | 55 --- idea/src/META-INF/plugin.xml | 3 - .../IdeaExternalAnnotationsProvider.java | 50 --- 11 files changed, 81 insertions(+), 1274 deletions(-) create mode 100644 compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CoreExternalAnnotationsManager.java delete mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/ClassUtil.java delete mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/CoreAnnotationsProvider.java delete mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/ExternalAnnotationsProvider.java delete mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/PsiExpressionTrimRenderer.java delete mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/PsiFormatUtil.java delete mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/PsiFormatUtilBase.java delete mode 100644 idea/src/org/jetbrains/jet/plugin/extAnnotations/IdeaExternalAnnotationsProvider.java diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CoreExternalAnnotationsManager.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CoreExternalAnnotationsManager.java new file mode 100644 index 00000000000..c752872ae89 --- /dev/null +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CoreExternalAnnotationsManager.java @@ -0,0 +1,73 @@ +/* + * Copyright 2010-2012 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.jet.cli.jvm.compiler; + +import com.intellij.codeInsight.BaseExternalAnnotationsManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Evgeny Gerashchenko + * @since 14 August 2012 + */ +public class CoreExternalAnnotationsManager extends BaseExternalAnnotationsManager { + static { + // This is an ugly workaround for JDOM 1.1 used from application started from Ant 1.8 without forking + System.setProperty("javax.xml.parsers.SAXParserFactory", "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"); + } + + private final List externalAnnotationsRoots = new ArrayList(); + + public CoreExternalAnnotationsManager(@NotNull PsiManager psiManager) { + super(psiManager); + } + + public void addExternalAnnotationsRoot(VirtualFile externalAnnotationsRoot) { + externalAnnotationsRoots.add(externalAnnotationsRoot); + } + + @Override + protected boolean hasAnyAnnotationsRoots() { + return true; + } + + @NotNull + @Override + protected List getExternalAnnotationsRoots(@NotNull VirtualFile libraryFile) { + return externalAnnotationsRoots; + } + + @Override + public void annotateExternally(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFQName, @NotNull PsiFile fromFile, + PsiNameValuePair[] value) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean deannotate(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFQN) { + throw new UnsupportedOperationException(); + } + + @Override + public AnnotationPlace chooseAnnotationsPlace(@NotNull PsiElement element) { + throw new UnsupportedOperationException(); + } +} diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java index a1ed9f82693..2b119aec41f 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java @@ -16,6 +16,7 @@ package org.jetbrains.jet.cli.jvm.compiler; +import com.intellij.codeInsight.ExternalAnnotationsManager; import com.intellij.core.CoreJavaFileManager; import com.intellij.core.JavaCoreApplicationEnvironment; import com.intellij.core.JavaCoreProjectEnvironment; @@ -36,13 +37,10 @@ import org.jetbrains.jet.asJava.JavaElementFinder; import org.jetbrains.jet.cli.jvm.JVMConfigurationKeys; import org.jetbrains.jet.config.CommonConfigurationKeys; import org.jetbrains.jet.config.CompilerConfiguration; -import org.jetbrains.jet.lang.parsing.JetParser; import org.jetbrains.jet.lang.parsing.JetParserDefinition; import org.jetbrains.jet.lang.parsing.JetScriptDefinitionProvider; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.java.JetFilesProvider; -import org.jetbrains.jet.lang.resolve.java.extAnnotations.CoreAnnotationsProvider; -import org.jetbrains.jet.lang.resolve.java.extAnnotations.ExternalAnnotationsProvider; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; import org.jetbrains.jet.plugin.JetFileType; import org.jetbrains.jet.utils.PathUtil; @@ -60,7 +58,7 @@ public class JetCoreEnvironment { private final JavaCoreProjectEnvironment projectEnvironment; private final List sourceFiles = new ArrayList(); - private final CoreAnnotationsProvider annotationsProvider; + private final CoreExternalAnnotationsManager annotationsManager; private final CompilerConfiguration configuration; @@ -89,8 +87,8 @@ public class JetCoreEnvironment { .getExtensionPoint(PsiElementFinder.EP_NAME) .registerExtension(new JavaElementFinder(project)); - annotationsProvider = new CoreAnnotationsProvider(); - project.registerService(ExternalAnnotationsProvider.class, annotationsProvider); + annotationsManager = new CoreExternalAnnotationsManager(project.getComponent(PsiManager.class)); + project.registerService(ExternalAnnotationsManager.class, annotationsManager); for (File path : configuration.getList(JVMConfigurationKeys.CLASSPATH_KEY)) { addToClasspath(path); @@ -123,7 +121,7 @@ public class JetCoreEnvironment { } private void addExternalAnnotationsRoot(VirtualFile root) { - annotationsProvider.addExternalAnnotationsRoot(root); + annotationsManager.addExternalAnnotationsRoot(root); } private void addSources(File file) { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 9ea0ffdd520..44f298cdf4a 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve.java; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import com.intellij.codeInsight.ExternalAnnotationsManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.psi.*; @@ -31,7 +32,6 @@ import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.constants.*; import org.jetbrains.jet.lang.resolve.constants.StringValue; -import org.jetbrains.jet.lang.resolve.java.extAnnotations.ExternalAnnotationsProvider; import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation; import org.jetbrains.jet.lang.resolve.java.kt.PsiAnnotationWithFlags; import org.jetbrains.jet.lang.resolve.name.FqName; @@ -1617,7 +1617,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes result.addAll(Arrays.asList(list.getAnnotations())); } - PsiAnnotation[] externalAnnotations = ExternalAnnotationsProvider.getInstance(owner.getProject()).findExternalAnnotations(owner); + PsiAnnotation[] externalAnnotations = ExternalAnnotationsManager.getInstance(owner.getProject()).findExternalAnnotations(owner); if (externalAnnotations != null) { result.addAll(Arrays.asList(externalAnnotations)); } @@ -1635,6 +1635,6 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes } } - return ExternalAnnotationsProvider.getInstance(owner.getProject()).findExternalAnnotation(owner, fqName); + return ExternalAnnotationsManager.getInstance(owner.getProject()).findExternalAnnotation(owner, fqName); } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/ClassUtil.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/ClassUtil.java deleted file mode 100644 index d713912316c..00000000000 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/ClassUtil.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 2010-2012 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.jet.lang.resolve.java.extAnnotations; - -import com.intellij.openapi.util.Comparing; -import com.intellij.psi.*; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.util.StringBuilderSpinAllocator; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * This class is copied from IDEA. - * This class should be eliminated when Kotlin will depend on IDEA 12.x (KT-2326) - * @author Evgeny Gerashchenko - * @since 6/26/12 - */ -@Deprecated -public class ClassUtil { - private ClassUtil() {} - - public static void formatClassName(@NotNull final PsiClass aClass, final StringBuilder buf) { - final String qName = aClass.getQualifiedName(); - if (qName != null) { - buf.append(qName); - } - else { - final PsiClass parentClass = getContainerClass(aClass); - if (parentClass != null) { - formatClassName(parentClass, buf); - buf.append("$"); - buf.append(getNonQualifiedClassIdx(aClass)); - final String name = aClass.getName(); - if (name != null) { - buf.append(name); - } - } - } - } - - @Nullable - private static PsiClass getContainerClass(final PsiClass aClass) { - PsiElement parent = aClass.getContext(); - while (parent != null && !(parent instanceof PsiClass)) { - parent = parent.getContext(); - } - return (PsiClass)parent; - } - - public static int getNonQualifiedClassIdx(@NotNull final PsiClass psiClass) { - final int[] result = {-1}; - final PsiClass containingClass = getContainerClass(psiClass); - if (containingClass != null) { - containingClass.accept(new JavaRecursiveElementVisitor() { - private int myCurrentIdx = 0; - - @Override public void visitElement(PsiElement element) { - if (result[0] == -1) { - super.visitElement(element); - } - } - - @Override public void visitClass(PsiClass aClass) { - super.visitClass(aClass); - if (aClass.getQualifiedName() == null) { - myCurrentIdx++; - if (psiClass == aClass) { - result[0] = myCurrentIdx; - } - } - } - }); - } - return result[0]; - } - - public static PsiClass findNonQualifiedClassByIndex(final String indexName, @NotNull final PsiClass containingClass, - final boolean jvmCompatible) { - String prefix = getDigitPrefix(indexName); - final int idx = prefix.length() > 0 ? Integer.parseInt(prefix) : -1; - final String name = prefix.length() < indexName.length() ? indexName.substring(prefix.length()) : null; - final PsiClass[] result = new PsiClass[1]; - containingClass.accept(new JavaRecursiveElementVisitor() { - private int myCurrentIdx = 0; - - @Override public void visitElement(PsiElement element) { - if (result[0] == null) { - super.visitElement(element); - } - } - - @Override public void visitClass(PsiClass aClass) { - if (!jvmCompatible) { - super.visitClass(aClass); - if (aClass.getQualifiedName() == null) { - myCurrentIdx++; - if (myCurrentIdx == idx && Comparing.strEqual(name, aClass.getName())) { - result[0] = aClass; - } - } - return; - } - if (aClass == containingClass) { - super.visitClass(aClass); - return; - } - if (Comparing.strEqual(name, aClass.getName())) { - myCurrentIdx++; - if (myCurrentIdx == idx || idx == -1) { - result[0] = aClass; - } - } - } - - @Override public void visitTypeParameter(final PsiTypeParameter classParameter) { - if (!jvmCompatible) { - super.visitTypeParameter(classParameter); - } - else { - visitElement(classParameter); - } - } - }); - return result[0]; - } - - private static String getDigitPrefix(final String indexName) { - final StringBuilder builder = StringBuilderSpinAllocator.alloc(); - try { - for (int i = 0; i < indexName.length(); i++) { - final char c = indexName.charAt(i); - if (Character.isDigit(c)) { - builder.append(c); - } - else { - break; - } - } - return builder.toString(); - } - finally { - StringBuilderSpinAllocator.dispose(builder); - } - } - - - @Nullable - public static PsiClass findPsiClass(final PsiManager psiManager, - String externalName, - PsiClass psiClass, - boolean jvmCompatible) { - return findPsiClass(psiManager, externalName, psiClass, jvmCompatible, GlobalSearchScope.allScope(psiManager.getProject())); - } - - @Nullable - public static PsiClass findPsiClass(final PsiManager psiManager, - String externalName, - @Nullable PsiClass psiClass, - boolean jvmCompatible, - final GlobalSearchScope scope) { - final int topIdx = externalName.indexOf('$'); - if (topIdx > -1) { - if (psiClass == null) { - psiClass = JavaPsiFacade.getInstance(psiManager.getProject()) - .findClass(externalName.substring(0, topIdx), scope); - } - if (psiClass == null) return null; - externalName = externalName.substring(topIdx + 1); - return findSubclass(psiManager, externalName, psiClass, jvmCompatible); - } else { - return JavaPsiFacade.getInstance(psiManager.getProject()).findClass(externalName, scope); - } - } - - @Nullable - private static PsiClass findSubclass(final PsiManager psiManager, - final String externalName, - final PsiClass psiClass, - final boolean jvmCompatible) { - final int nextIdx = externalName.indexOf('$'); - if (nextIdx > -1) { - final PsiClass anonymousClass = findNonQualifiedClassByIndex(externalName.substring(0, nextIdx), psiClass, jvmCompatible); - if (anonymousClass == null) return null; - return findPsiClass(psiManager, externalName.substring(nextIdx), anonymousClass, jvmCompatible); - } - else { - return findNonQualifiedClassByIndex(externalName, psiClass, jvmCompatible); - } - } -} \ No newline at end of file diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/CoreAnnotationsProvider.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/CoreAnnotationsProvider.java deleted file mode 100644 index 1bd53231f41..00000000000 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/CoreAnnotationsProvider.java +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright 2010-2012 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.jet.lang.resolve.java.extAnnotations; - -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.JDOMUtil; -import com.intellij.openapi.util.io.StreamUtil; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.*; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.util.IncorrectOperationException; -import com.intellij.util.StringBuilderSpinAllocator; -import com.intellij.util.containers.ConcurrentWeakHashMap; -import com.intellij.util.containers.ConcurrentWeakValueHashMap; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.MultiMap; -import org.jdom.Document; -import org.jdom.Element; -import org.jdom.JDOMException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.IOException; -import java.util.*; -import java.util.concurrent.ConcurrentMap; - -/** - * This class is copied from IDEA. - * This class should be eliminated when Kotlin will depend on IDEA 12.x (KT-2326) - * @author Evgeny Gerashchenko - * @since 6/26/12 - */ -@Deprecated -public class CoreAnnotationsProvider extends ExternalAnnotationsProvider { - static { - // This is an ugly workaround for JDOM 1.1 used from application started from Ant 1.8 without forking - System.setProperty("javax.xml.parsers.SAXParserFactory", "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"); - } - - private static final Logger LOG = Logger.getInstance("#" + CoreAnnotationsProvider.class.getName()); - @NotNull private static final List NULL = new ArrayList(); - @NotNull private final ConcurrentMap> - myExternalAnnotations = new ConcurrentWeakValueHashMap>(); - - private List externalAnnotationsRoots = new ArrayList(); - - public CoreAnnotationsProvider() { - } - - @Nullable - private static String getExternalName(PsiModifierListOwner listOwner, boolean showParamName) { - return PsiFormatUtil.getExternalName(listOwner, showParamName, Integer.MAX_VALUE); - } - - @Nullable - private static String getFQN(String packageName, @Nullable VirtualFile virtualFile) { - if (virtualFile == null) return null; - return StringUtil.getQualifiedName(packageName, virtualFile.getNameWithoutExtension()); - } - - @Nullable - protected static String getNormalizedExternalName(@NotNull PsiModifierListOwner owner) { - String externalName = getExternalName(owner, true); - if (externalName != null) { - if (owner instanceof PsiParameter && owner.getParent() instanceof PsiParameterList) { - final PsiMethod method = PsiTreeUtil.getParentOfType(owner, PsiMethod.class); - if (method != null) { - externalName = - externalName.substring(0, externalName.lastIndexOf(' ') + 1) + method.getParameterList().getParameterIndex((PsiParameter)owner); - } - } - final int idx = externalName.indexOf('('); - if (idx == -1) return externalName; - final StringBuilder buf = StringBuilderSpinAllocator.alloc(); - try { - final int rightIdx = externalName.indexOf(')'); - final String[] params = externalName.substring(idx + 1, rightIdx).split(","); - buf.append(externalName.substring(0, idx + 1)); - for (String param : params) { - param = param.trim(); - final int spaceIdx = param.indexOf(' '); - buf.append(spaceIdx > -1 ? param.substring(0, spaceIdx) : param).append(", "); - } - return StringUtil.trimEnd(buf.toString(), ", ") + externalName.substring(rightIdx); - } - finally { - StringBuilderSpinAllocator.dispose(buf); - } - } - return externalName; - } - - @Override - @Nullable - public PsiAnnotation findExternalAnnotation(@NotNull final PsiModifierListOwner listOwner, @NotNull final String annotationFQN) { - return collectExternalAnnotations(listOwner).get(annotationFQN); - } - - @Override - @Nullable - public PsiAnnotation[] findExternalAnnotations(@NotNull final PsiModifierListOwner listOwner) { - final Map result = collectExternalAnnotations(listOwner); - return result.isEmpty() ? null : result.values().toArray(new PsiAnnotation[result.size()]); - } - - private final Map> cache = new ConcurrentWeakHashMap>(); - @NotNull - private Map collectExternalAnnotations(@NotNull final PsiModifierListOwner listOwner) { - Map map = cache.get(listOwner); - if (map == null) { - map = doCollect(listOwner); - cache.put(listOwner, map); - } - return map; - } - - public void addExternalAnnotationsRoot(VirtualFile externalAnnotationsRoot) { - externalAnnotationsRoots.add(externalAnnotationsRoot); - } - - private Map> annotationsFileToData = new HashMap>(); - private Map annotationsFileToModificationStamp = new HashMap(); - @NotNull - private MultiMap getDataFromFile(@NotNull PsiFile file) { - if (annotationsFileToData.containsKey(file) && file.getModificationStamp() == annotationsFileToModificationStamp.get(file)) { - return annotationsFileToData.get(file); - } - else { - MultiMap data = new MultiMap(); - annotationsFileToData.put(file, data); - annotationsFileToModificationStamp.put(file, file.getModificationStamp()); - - Document document; - try { - //noinspection ConstantConditions - document = JDOMUtil.loadDocument(escapeAttributes(StreamUtil.readText(file.getVirtualFile().getInputStream()))); - } - catch (IOException e) { - LOG.error(e); - return data; - } - catch (JDOMException e) { - LOG.error(e); - return data; - } - Element rootElement = document.getRootElement(); - if (rootElement == null) return data; - - //noinspection unchecked - for (Element element : (List) rootElement.getChildren()) { - String ownerName = element.getAttributeValue("name"); - if (ownerName == null) continue; - //noinspection unchecked - for (Element annotationElement : (List) element.getChildren()) { - String annotationFQN = annotationElement.getAttributeValue("name"); - StringBuilder buf = new StringBuilder(); - //noinspection unchecked - for (Element annotationParameter : (List) annotationElement.getChildren()) { - buf.append(","); - String nameValue = annotationParameter.getAttributeValue("name"); - if (nameValue != null) { - buf.append(nameValue).append("="); - } - buf.append(annotationParameter.getAttributeValue("val")); - } - String annotationText = "@" + annotationFQN + (buf.length() > 0 ? "(" + StringUtil.trimStart(buf.toString(), ",") + ")" : ""); - data.putValue(ownerName, new AnnotationData(annotationFQN, annotationText)); - } - } - - return data; - } - } - - private Map doCollect(@NotNull PsiModifierListOwner listOwner) { - final List files = findExternalAnnotationsFiles(listOwner); - if (files == null) { - return Collections.emptyMap(); - } - Map result = new HashMap(); - String externalName = getExternalName(listOwner, false); - String oldExternalName = getNormalizedExternalName(listOwner); - - for (PsiFile file : files) { - if (!file.isValid()) continue; - MultiMap fileData = getDataFromFile(file); - for (AnnotationData annotationData : ContainerUtil.concat(fileData.get(externalName), fileData.get(oldExternalName))) { - try { - result.put(annotationData.annotationClassFqName, - JavaPsiFacade.getInstance(listOwner.getProject()).getElementFactory().createAnnotationFromText( - annotationData.annotationText, null)); - } - catch (IncorrectOperationException e) { - LOG.error(e); - } - } - } - return result; - } - - @Nullable - private List findExternalAnnotationsFiles(@NotNull PsiModifierListOwner listOwner) { - final PsiFile containingFile = listOwner.getContainingFile(); - if (!(containingFile instanceof PsiJavaFile)) { - return null; - } - final PsiJavaFile javaFile = (PsiJavaFile)containingFile; - final String packageName = javaFile.getPackageName(); - final VirtualFile virtualFile = containingFile.getVirtualFile(); - String fqn = getFQN(packageName, virtualFile); - if (fqn == null) return null; - final List files = myExternalAnnotations.get(fqn); - if (files == NULL) return null; - if (files != null) { - for (Iterator it = files.iterator(); it.hasNext();) { - if (!it.next().isValid()) it.remove(); - } - return files; - } - - if (virtualFile == null) { - return null; - } - - List possibleAnnotationsXmls = new ArrayList(); - for (VirtualFile root : externalAnnotationsRoots) { - final VirtualFile ext = root.findFileByRelativePath(packageName.replace(".", "/") + "/" + "annotations.xml"); - if (ext == null) continue; - final PsiFile psiFile = listOwner.getManager().findFile(ext); - possibleAnnotationsXmls.add(psiFile); - } - if (!possibleAnnotationsXmls.isEmpty()) { - myExternalAnnotations.put(fqn, possibleAnnotationsXmls); - return possibleAnnotationsXmls; - } - myExternalAnnotations.put(fqn, NULL); - return null; - } - - - // This method is used for legacy reasons. - // Old external annotations sometimes are bad XML: they have "<" and ">" characters in attributes values. To prevent SAX parser from - // failing, we escape attributes values. - @NotNull - private static String escapeAttributes(@NotNull String invalidXml) { - // We assume that XML has single- and double-quote characters only for attribute values, therefore we don't any complex parsing, - // just split by ['"] regexp instead - - // For PERFORMANCE REASONS this is written by hand instead of using regular expressions - // This implementation turned out to be too slow: - // String[] split = invalidXml.split("[\"\']"); - // assert split.length % 2 == 1; - // for (int i = 1; i < split.length; i += 2) { - // split[i] = split[i].replace("<", "<").replace(">", ">"); - // } - // return StringUtil.join(split, "\""); - - StringBuilder sb = new StringBuilder(); - boolean inQuotes = false; - for (int i = 0; i < invalidXml.length(); i++) { - char c = invalidXml.charAt(i); - switch (c) { - case '\'': - case '\"': - inQuotes = !inQuotes; - sb.append('\"'); - break; - case '<': - if (inQuotes) { - sb.append("<"); - } - else { - sb.append(c); - } - break; - case '>': - if (inQuotes) { - sb.append(">"); - } - else { - sb.append(c); - } - break; - default: - sb.append(c); - break; - } - } - return sb.toString(); - } - - private static class AnnotationData { - public String annotationClassFqName; - public String annotationText; - - private AnnotationData(String annotationClassFqName, String annotationText) { - this.annotationClassFqName = annotationClassFqName; - this.annotationText = annotationText; - } - } -} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/ExternalAnnotationsProvider.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/ExternalAnnotationsProvider.java deleted file mode 100644 index 32d293207e6..00000000000 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/ExternalAnnotationsProvider.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2010-2012 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.jet.lang.resolve.java.extAnnotations; - -import com.intellij.openapi.components.ServiceManager; -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiAnnotation; -import com.intellij.psi.PsiModifierListOwner; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * This class should be eliminated when Kotlin will depend on IDEA 12.x (KT-2326) - * @author Evgeny Gerashchenko - * @since 6/26/12 - */ -@Deprecated -public abstract class ExternalAnnotationsProvider { - @Nullable - public abstract PsiAnnotation findExternalAnnotation(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFQN); - - @Nullable - public abstract PsiAnnotation[] findExternalAnnotations(@NotNull PsiModifierListOwner listOwner); - - public static ExternalAnnotationsProvider getInstance(@NotNull Project project) { - return ServiceManager.getService(project, ExternalAnnotationsProvider.class); - } -} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/PsiExpressionTrimRenderer.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/PsiExpressionTrimRenderer.java deleted file mode 100644 index 2e1da0eae33..00000000000 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/PsiExpressionTrimRenderer.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright 2010-2012 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. - */ - -/* - * User: anna - * Date: 28-Oct-2008 - */ -package org.jetbrains.jet.lang.resolve.java.extAnnotations; - -import com.intellij.psi.*; -import com.intellij.util.Function; - -/** - * This class is copied from IDEA. - * This class should be eliminated when Kotlin will depend on IDEA 12.x (KT-2326) - * @author Evgeny Gerashchenko - * @since 6/26/12 - */ -@Deprecated -public class PsiExpressionTrimRenderer extends JavaRecursiveElementWalkingVisitor { - private final StringBuilder myBuf; - - public PsiExpressionTrimRenderer(final StringBuilder buf) { - myBuf = buf; - } - - @Override - public void visitExpression(final PsiExpression expression) { - myBuf.append(expression.getText()); - } - - @Override - public void visitInstanceOfExpression(final PsiInstanceOfExpression expression) { - expression.getOperand().accept(this); - myBuf.append(" ").append(PsiKeyword.INSTANCEOF).append(" "); - final PsiTypeElement checkType = expression.getCheckType(); - if (checkType != null) { - myBuf.append(checkType.getText()); - } - } - - @Override - public void visitParenthesizedExpression(final PsiParenthesizedExpression expression) { - myBuf.append("("); - final PsiExpression expr = expression.getExpression(); - if (expr != null) { - expr.accept(this); - } - myBuf.append(")"); - } - - @Override - public void visitTypeCastExpression(final PsiTypeCastExpression expression) { - final PsiTypeElement castType = expression.getCastType(); - if (castType != null) { - myBuf.append("(").append(castType.getText()).append(")"); - } - final PsiExpression operand = expression.getOperand(); - if (operand != null) { - operand.accept(this); - } - } - - @Override - public void visitArrayAccessExpression(final PsiArrayAccessExpression expression) { - expression.getArrayExpression().accept(this); - myBuf.append("["); - final PsiExpression indexExpression = expression.getIndexExpression(); - if (indexExpression != null) { - indexExpression.accept(this); - } - myBuf.append("]"); - } - - @Override - public void visitPrefixExpression(final PsiPrefixExpression expression) { - myBuf.append(expression.getOperationSign().getText()); - final PsiExpression operand = expression.getOperand(); - if (operand != null) { - operand.accept(this); - } - } - - @Override - public void visitPostfixExpression(final PsiPostfixExpression expression) { - expression.getOperand().accept(this); - myBuf.append(expression.getOperationSign().getText()); - } - - @Override - public void visitPolyadicExpression(PsiPolyadicExpression expression) { - PsiExpression[] operands = expression.getOperands(); - for (int i = 0; i < operands.length; i++) { - PsiExpression operand = operands[i]; - if (i != 0) { - PsiJavaToken token = expression.getTokenBeforeOperand(operand); - myBuf.append(" ").append(token.getText()).append(" "); - } - operand.accept(this); - } - } - - @Override - public void visitConditionalExpression(final PsiConditionalExpression expression) { - expression.getCondition().accept(this); - - myBuf.append(" ? "); - final PsiExpression thenExpression = expression.getThenExpression(); - if (thenExpression != null) { - thenExpression.accept(this); - } - - myBuf.append(" : "); - final PsiExpression elseExpression = expression.getElseExpression(); - if (elseExpression != null) { - elseExpression.accept(this); - } - } - - @Override - public void visitAssignmentExpression(final PsiAssignmentExpression expression) { - expression.getLExpression().accept(this); - myBuf.append(expression.getOperationSign().getText()); - final PsiExpression rExpression = expression.getRExpression(); - if (rExpression != null) { - rExpression.accept(this); - } - } - - @Override - public void visitReferenceExpression(final PsiReferenceExpression expr) { - final PsiExpression qualifierExpression = expr.getQualifierExpression(); - if (qualifierExpression != null) { - qualifierExpression.accept(this); - myBuf.append("."); - } - myBuf.append(expr.getReferenceName()); - - } - - @Override - public void visitMethodCallExpression(final PsiMethodCallExpression expr) { - expr.getMethodExpression().accept(this); - expr.getArgumentList().accept(this); - } - - - @Override - public void visitArrayInitializerExpression(final PsiArrayInitializerExpression expression) { - myBuf.append("{"); - boolean first = true; - for (PsiExpression expr : expression.getInitializers()) { - if (!first) { - myBuf.append(", "); - } - first = false; - expr.accept(this); - } - myBuf.append("}"); - } - - @Override - public void visitExpressionList(final PsiExpressionList list) { - final PsiExpression[] args = list.getExpressions(); - if (args.length > 0) { - myBuf.append("(...)"); - } - else { - myBuf.append("()"); - } - } - - @Override - public void visitNewExpression(final PsiNewExpression expr) { - final PsiAnonymousClass anonymousClass = expr.getAnonymousClass(); - - final PsiExpressionList argumentList = expr.getArgumentList(); - - if (anonymousClass != null) { - myBuf.append(PsiKeyword.NEW).append(" ").append(anonymousClass.getBaseClassType().getPresentableText()); - if (argumentList != null) argumentList.accept(this); - myBuf.append(" {...}"); - } - else { - final PsiJavaCodeReferenceElement reference = expr.getClassReference(); - if (reference != null) { - myBuf.append(PsiKeyword.NEW).append(" ").append(reference.getText()); - - final PsiExpression[] arrayDimensions = expr.getArrayDimensions(); - final PsiType type = expr.getType(); - final int dimensions = type != null ? type.getArrayDimensions() : arrayDimensions.length; - if (arrayDimensions.length > 0) myBuf.append("["); - for (int i = 0, arrayDimensionsLength = arrayDimensions.length; i < dimensions; i++) { - final PsiExpression dimension = i < arrayDimensionsLength ? arrayDimensions[i] : null; - if (i > 0) myBuf.append("]["); - if (dimension != null) { - dimension.accept(this); - } - } - if (arrayDimensions.length > 0) myBuf.append("]"); - - if (argumentList != null) { - argumentList.accept(this); - } - - final PsiArrayInitializerExpression arrayInitializer = expr.getArrayInitializer(); - if (arrayInitializer != null) { - arrayInitializer.accept(this); - } - } - else { - myBuf.append(expr.getText()); - } - } - } - - public static String render(PsiExpression expression) { - StringBuilder buf = new StringBuilder(); - expression.accept(new PsiExpressionTrimRenderer(buf)); - return buf.toString(); - } -} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/PsiFormatUtil.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/PsiFormatUtil.java deleted file mode 100644 index 3a14a2bda70..00000000000 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/PsiFormatUtil.java +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Copyright 2010-2012 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.jet.lang.resolve.java.extAnnotations; - -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.*; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.PsiUtil; -import com.intellij.psi.util.TypeConversionUtil; -import org.intellij.lang.annotations.MagicConstant; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * This class is copied from IDEA. - * This class should be eliminated when Kotlin will depend on IDEA 12.x (KT-2326) - * @author Evgeny Gerashchenko - * @since 6/26/12 - */ -@Deprecated -public class PsiFormatUtil extends PsiFormatUtilBase { - @MagicConstant(flags = {SHOW_MODIFIERS, SHOW_TYPE, TYPE_AFTER, SHOW_CONTAINING_CLASS, SHOW_FQ_NAME, SHOW_NAME, SHOW_MODIFIERS, SHOW_INITIALIZER, SHOW_RAW_TYPE, SHOW_RAW_NON_TOP_TYPE, SHOW_FQ_CLASS_NAMES}) - public @interface FormatVariableOptions {} - - public static String formatVariable(PsiVariable variable, @FormatVariableOptions int options, PsiSubstitutor substitutor){ - StringBuilder buffer = new StringBuilder(); - formatVariable(variable, options, substitutor,buffer); - return buffer.toString(); - } - private static void formatVariable(PsiVariable variable, - @FormatVariableOptions int options, - PsiSubstitutor substitutor, - @NotNull StringBuilder buffer){ - if ((options & SHOW_MODIFIERS) != 0 && (options & MODIFIERS_AFTER) == 0){ - formatModifiers(variable, options,buffer); - } - if ((options & SHOW_TYPE) != 0 && (options & TYPE_AFTER) == 0){ - appendSpaceIfNeeded(buffer); - buffer.append(formatType(variable.getType(), options, substitutor)); - } - if (variable instanceof PsiField && (options & SHOW_CONTAINING_CLASS) != 0){ - PsiClass aClass = ((PsiField)variable).getContainingClass(); - if (aClass != null){ - String className = aClass.getName(); - if (className != null) { - appendSpaceIfNeeded(buffer); - if ((options & SHOW_FQ_NAME) != 0){ - String qName = aClass.getQualifiedName(); - if (qName != null){ - buffer.append(qName); - } - else{ - buffer.append(className); - } - } - else{ - buffer.append(className); - } - buffer.append('.'); - } - } - if ((options & SHOW_NAME) != 0){ - buffer.append(variable.getName()); - } - } - else{ - if ((options & SHOW_NAME) != 0){ - String name = variable.getName(); - if (StringUtil.isNotEmpty(name)){ - appendSpaceIfNeeded(buffer); - buffer.append(name); - } - } - } - if ((options & SHOW_TYPE) != 0 && (options & TYPE_AFTER) != 0){ - if ((options & SHOW_NAME) != 0 && variable.getName() != null){ - buffer.append(':'); - } - buffer.append(formatType(variable.getType(), options, substitutor)); - } - if ((options & SHOW_MODIFIERS) != 0 && (options & MODIFIERS_AFTER) != 0){ - formatModifiers(variable, options,buffer); - } - if ((options & SHOW_INITIALIZER) != 0){ - PsiExpression initializer = variable.getInitializer(); - if (initializer != null){ - buffer.append(" = "); - String text = PsiExpressionTrimRenderer.render(initializer); - int index1 = text.lastIndexOf('\n'); - if (index1 < 0) index1 = text.length(); - int index2 = text.lastIndexOf('\r'); - if (index2 < 0) index2 = text.length(); - int index = Math.min(index1, index2); - buffer.append(text.substring(0, index)); - if (index < text.length()) { - buffer.append(" ..."); - } - } - } - } - - @MagicConstant(flags = {SHOW_MODIFIERS, MODIFIERS_AFTER, SHOW_TYPE, TYPE_AFTER, SHOW_CONTAINING_CLASS, SHOW_FQ_NAME, SHOW_NAME, SHOW_PARAMETERS, SHOW_THROWS, SHOW_RAW_TYPE, SHOW_RAW_NON_TOP_TYPE, SHOW_FQ_CLASS_NAMES}) - public @interface FormatMethodOptions {} - - private static void formatMethod(PsiMethod method, PsiSubstitutor substitutor, @FormatMethodOptions int options, @FormatVariableOptions int parameterOptions, int maxParametersToShow, StringBuilder buffer){ - if ((options & SHOW_MODIFIERS) != 0 && (options & MODIFIERS_AFTER) == 0){ - formatModifiers(method, options,buffer); - } - if ((options & SHOW_TYPE) != 0 && (options & TYPE_AFTER) == 0){ - PsiType type = method.getReturnType(); - if (type != null){ - appendSpaceIfNeeded(buffer); - buffer.append(formatType(type, options, substitutor)); - } - } - if ((options & SHOW_CONTAINING_CLASS) != 0){ - PsiClass aClass = method.getContainingClass(); - if (aClass != null){ - appendSpaceIfNeeded(buffer); - String name = aClass.getName(); - if (name != null) { - if ((options & SHOW_FQ_NAME) != 0){ - String qName = aClass.getQualifiedName(); - if (qName != null){ - buffer.append(qName); - } - else{ - buffer.append(name); - } - } - else{ - buffer.append(name); - } - buffer.append('.'); - } - } - if ((options & SHOW_NAME) != 0){ - buffer.append(method.getName()); - } - } - else{ - if ((options & SHOW_NAME) != 0){ - appendSpaceIfNeeded(buffer); - buffer.append(method.getName()); - } - } - if ((options & SHOW_PARAMETERS) != 0){ - buffer.append('('); - PsiParameter[] parms = method.getParameterList().getParameters(); - for(int i = 0; i < Math.min(parms.length, maxParametersToShow); i++) { - PsiParameter parm = parms[i]; - if (i > 0){ - buffer.append(", "); - } - buffer.append(formatVariable(parm, parameterOptions, substitutor)); - } - if(parms.length > maxParametersToShow) { - buffer.append (", ..."); - } - buffer.append(')'); - } - if ((options & SHOW_TYPE) != 0 && (options & TYPE_AFTER) != 0){ - PsiType type = method.getReturnType(); - if (type != null){ - if (buffer.length() > 0){ - buffer.append(':'); - } - buffer.append(formatType(type, options, substitutor)); - } - } - if ((options & SHOW_MODIFIERS) != 0 && (options & MODIFIERS_AFTER) != 0){ - formatModifiers(method, options,buffer); - } - if ((options & SHOW_THROWS) != 0){ - String throwsText = formatReferenceList(method.getThrowsList(), options); - if (!throwsText.isEmpty()){ - appendSpaceIfNeeded(buffer); - //noinspection HardCodedStringLiteral - buffer.append("throws "); - buffer.append(throwsText); - } - } - } - - - private static void formatModifiers(PsiElement element, int options, StringBuilder buffer) throws IllegalArgumentException{ - PsiModifierList list; - boolean isInterface = false; - if (element instanceof PsiVariable){ - list = ((PsiVariable)element).getModifierList(); - } - else if (element instanceof PsiMethod){ - list = ((PsiMethod)element).getModifierList(); - } - else if (element instanceof PsiClass){ - isInterface = ((PsiClass)element).isInterface(); - list = ((PsiClass)element).getModifierList(); - if (list == null) return; - } - else if (element instanceof PsiClassInitializer){ - list = ((PsiClassInitializer)element).getModifierList(); - if (list == null) return; - } - else{ - throw new IllegalArgumentException(); - } - if (list == null) return; - if ((options & SHOW_REDUNDANT_MODIFIERS) == 0 - ? list.hasExplicitModifier(PsiModifier.PUBLIC) - : list.hasModifierProperty(PsiModifier.PUBLIC)) { - appendModifier(buffer, PsiModifier.PUBLIC); - } - - if (list.hasModifierProperty(PsiModifier.PROTECTED)){ - appendModifier(buffer, PsiModifier.PROTECTED); - } - if (list.hasModifierProperty(PsiModifier.PRIVATE)){ - appendModifier(buffer, PsiModifier.PRIVATE); - } - - if ((options & SHOW_REDUNDANT_MODIFIERS) == 0 - ? list.hasExplicitModifier(PsiModifier.PACKAGE_LOCAL) - : list.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) { - if (element instanceof PsiClass && element.getParent() instanceof PsiDeclarationStatement) {// local class - appendModifier(buffer, "local"); - } - else { - appendModifier(buffer, PsiBundle.visibilityPresentation(PsiModifier.PACKAGE_LOCAL)); - } - } - - if ((options & SHOW_REDUNDANT_MODIFIERS) == 0 - ? list.hasExplicitModifier(PsiModifier.STATIC) - : list.hasModifierProperty(PsiModifier.STATIC)) appendModifier(buffer, PsiModifier.STATIC); - - if (!isInterface && //cls modifier list - ((options & SHOW_REDUNDANT_MODIFIERS) == 0 - ? list.hasExplicitModifier(PsiModifier.ABSTRACT) - : list.hasModifierProperty(PsiModifier.ABSTRACT))) appendModifier(buffer, PsiModifier.ABSTRACT); - - if ((options & SHOW_REDUNDANT_MODIFIERS) == 0 - ? list.hasExplicitModifier(PsiModifier.FINAL) - : list.hasModifierProperty(PsiModifier.FINAL)) appendModifier(buffer, PsiModifier.FINAL); - - if (list.hasModifierProperty(PsiModifier.NATIVE) && (options & JAVADOC_MODIFIERS_ONLY) == 0){ - appendModifier(buffer, PsiModifier.NATIVE); - } - if (list.hasModifierProperty(PsiModifier.SYNCHRONIZED) && (options & JAVADOC_MODIFIERS_ONLY) == 0){ - appendModifier(buffer, PsiModifier.SYNCHRONIZED); - } - if (list.hasModifierProperty(PsiModifier.STRICTFP) && (options & JAVADOC_MODIFIERS_ONLY) == 0){ - appendModifier(buffer, PsiModifier.STRICTFP); - } - if (list.hasModifierProperty(PsiModifier.TRANSIENT) && - element instanceof PsiVariable // javac 5 puts transient attr for methods - ){ - appendModifier(buffer, PsiModifier.TRANSIENT); - } - if (list.hasModifierProperty(PsiModifier.VOLATILE)){ - appendModifier(buffer, PsiModifier.VOLATILE); - } - } - - private static void appendModifier(final StringBuilder buffer, final String modifier) { - appendSpaceIfNeeded(buffer); - buffer.append(modifier); - } - - public static String formatReferenceList(PsiReferenceList list, int options){ - StringBuilder buffer = new StringBuilder(); - PsiJavaCodeReferenceElement[] refs = list.getReferenceElements(); - for(int i = 0; i < refs.length; i++) { - PsiJavaCodeReferenceElement ref = refs[i]; - if (i > 0){ - buffer.append(", "); - } - buffer.append(formatReference(ref, options)); - } - return buffer.toString(); - } - - public static String formatType(PsiType type, int options, @NotNull PsiSubstitutor substitutor){ - type = substitutor.substitute(type); - if ((options & SHOW_RAW_TYPE) != 0) { - type = TypeConversionUtil.erasure(type); - } else if ((options & SHOW_RAW_NON_TOP_TYPE) != 0) { - if (!(PsiUtil.resolveClassInType(type) instanceof PsiTypeParameter)) { - final boolean preserveEllipsis = type instanceof PsiEllipsisType; - type = TypeConversionUtil.erasure(type); - if (preserveEllipsis && type instanceof PsiArrayType) { - type = new PsiEllipsisType(((PsiArrayType)type).getComponentType()); - } - } - } - return (options & SHOW_FQ_CLASS_NAMES) == 0 ? type.getPresentableText() : type.getInternalCanonicalText(); - } - - public static String formatReference(PsiJavaCodeReferenceElement ref, int options){ - return (options & SHOW_FQ_CLASS_NAMES) == 0 ? ref.getText() : ref.getCanonicalText(); - } - - @Nullable - public static String getExternalName(PsiModifierListOwner owner, final boolean showParamName, int maxParamsToShow) { - final StringBuilder builder = new StringBuilder(); - if (owner instanceof PsiClass) { - ClassUtil.formatClassName((PsiClass)owner, builder); - return builder.toString(); - } - final PsiClass psiClass = PsiTreeUtil.getParentOfType(owner, PsiClass.class, false); - if (psiClass == null) return null; - ClassUtil.formatClassName(psiClass, builder); - if (owner instanceof PsiMethod) { - builder.append(" "); - formatMethod((PsiMethod)owner, PsiSubstitutor.EMPTY, - SHOW_NAME | SHOW_FQ_NAME | SHOW_TYPE | SHOW_PARAMETERS | SHOW_FQ_CLASS_NAMES, - showParamName ? SHOW_NAME | SHOW_TYPE | SHOW_FQ_CLASS_NAMES : SHOW_TYPE | SHOW_FQ_CLASS_NAMES, maxParamsToShow, builder); - } - else if (owner instanceof PsiField) { - builder.append(" ").append(((PsiField)owner).getName()); - } - else if (owner instanceof PsiParameter) { - final PsiElement declarationScope = ((PsiParameter)owner).getDeclarationScope(); - if (!(declarationScope instanceof PsiMethod)) { - return null; - } - final PsiMethod psiMethod = (PsiMethod)declarationScope; - - builder.append(" "); - formatMethod(psiMethod, PsiSubstitutor.EMPTY, - SHOW_NAME | SHOW_FQ_NAME | SHOW_TYPE | SHOW_PARAMETERS | SHOW_FQ_CLASS_NAMES, - showParamName ? SHOW_NAME | SHOW_TYPE | SHOW_FQ_CLASS_NAMES : SHOW_TYPE | SHOW_FQ_CLASS_NAMES, maxParamsToShow, builder); - builder.append(" "); - - if (showParamName) { - formatVariable((PsiVariable)owner, SHOW_NAME, PsiSubstitutor.EMPTY, builder); - } - else { - builder.append(psiMethod.getParameterList().getParameterIndex((PsiParameter)owner)); - } - } - else { - return null; - } - return builder.toString(); - } -} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/PsiFormatUtilBase.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/PsiFormatUtilBase.java deleted file mode 100644 index c508120c0ea..00000000000 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/extAnnotations/PsiFormatUtilBase.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2010-2012 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.jet.lang.resolve.java.extAnnotations; - -import com.intellij.openapi.util.text.StringUtil; - -/** - * This class is copied from IDEA. - * This class should be eliminated when Kotlin will depend on IDEA 12.x (KT-2326) - * @author Evgeny Gerashchenko - * @since 6/26/12 - */ -@Deprecated -public abstract class PsiFormatUtilBase { - - public static final int SHOW_NAME = 0x0001; // variable, method, class - public static final int SHOW_TYPE = 0x0002; // variable, method - public static final int TYPE_AFTER = 0x0004; // variable, method - public static final int SHOW_MODIFIERS = 0x0008; // variable, method, class - public static final int MODIFIERS_AFTER = 0x0010; // variable, method, class - public static final int SHOW_REDUNDANT_MODIFIERS = 0x0020; // variable, method, class, modifier list - public static final int SHOW_PACKAGE_LOCAL = 0x0040; // variable, method, class, modifier list - public static final int SHOW_INITIALIZER = 0x0080; // variable - public static final int SHOW_PARAMETERS = 0x0100; // method - public static final int SHOW_THROWS = 0x0200; // method - public static final int SHOW_EXTENDS_IMPLEMENTS = 0x0400; // class - public static final int SHOW_FQ_NAME = 0x0800; // class, field, method - public static final int SHOW_CONTAINING_CLASS = 0x1000; // field, method - public static final int SHOW_FQ_CLASS_NAMES = 0x2000; // variable, method, class - public static final int JAVADOC_MODIFIERS_ONLY = 0x4000; // field, method, class - public static final int SHOW_ANONYMOUS_CLASS_VERBOSE = 0x8000; // class - public static final int SHOW_RAW_TYPE = 0x10000; //type - public static final int SHOW_RAW_NON_TOP_TYPE = 0x20000; - public static final int MAX_PARAMS_TO_SHOW = 7; - - protected static void appendSpaceIfNeeded(StringBuilder buffer) { - if (buffer.length() != 0 && !StringUtil.endsWithChar(buffer, ' ')) { - buffer.append(' '); - } - } -} diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 9b243c61055..011d013326a 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -76,9 +76,6 @@ - - diff --git a/idea/src/org/jetbrains/jet/plugin/extAnnotations/IdeaExternalAnnotationsProvider.java b/idea/src/org/jetbrains/jet/plugin/extAnnotations/IdeaExternalAnnotationsProvider.java deleted file mode 100644 index cdd5b96f5cf..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/extAnnotations/IdeaExternalAnnotationsProvider.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2010-2012 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.jet.plugin.extAnnotations; - -import com.intellij.codeInsight.ExternalAnnotationsManager; -import com.intellij.openapi.components.ApplicationComponent; -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiAnnotation; -import com.intellij.psi.PsiModifierListOwner; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.resolve.java.extAnnotations.ExternalAnnotationsProvider; - -/** - * This class is copied from IDEA. - * This class should be eliminated when Kotlin will depend on IDEA 12.x (KT-2326) - * @author Evgeny Gerashchenko - * @since 6/26/12 - */ -@Deprecated -public class IdeaExternalAnnotationsProvider extends ExternalAnnotationsProvider { - private final ExternalAnnotationsManager externalAnnotationsManager; - - public IdeaExternalAnnotationsProvider(ExternalAnnotationsManager externalAnnotationsManager) { - this.externalAnnotationsManager = externalAnnotationsManager; - } - - @Override - public synchronized PsiAnnotation findExternalAnnotation(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFQN) { - return externalAnnotationsManager.findExternalAnnotation(listOwner, annotationFQN); - } - - @Override - public synchronized PsiAnnotation[] findExternalAnnotations(@NotNull PsiModifierListOwner listOwner) { - return externalAnnotationsManager.findExternalAnnotations(listOwner); - } -} From 0adf6d615a6fd4ba8c135daa450e2d7273275161 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 14 Aug 2012 19:20:46 +0400 Subject: [PATCH 16/36] JetPositionManager now correctly calculates class names for a given position --- .../jetbrains/jet/codegen/JetTypeMapper.java | 10 +-- .../plugin/debugger/JetPositionManager.java | 65 +++++++------------ 2 files changed, 30 insertions(+), 45 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index aea38a49409..a86ab093492 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -1044,13 +1044,13 @@ public class JetTypeMapper { } } - public Collection allJvmNames(JetClassOrObject jetClass) { - Set result = new HashSet(); + @Nullable + public String getJvmInternalName(JetClassOrObject jetClass) { final ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, jetClass); - if (classDescriptor != null) { - result.add(mapType(classDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName()); + if (classDescriptor == null) { + return null; } - return result; + return mapType(classDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName(); } private static boolean isForceReal(JvmClassName className) { diff --git a/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java b/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java index a8aeeda8079..4cbf8658088 100644 --- a/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java +++ b/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java @@ -33,18 +33,14 @@ import com.sun.jdi.AbsentInformationException; import com.sun.jdi.Location; import com.sun.jdi.ReferenceType; import com.sun.jdi.request.ClassPrepareRequest; -import com.sun.jna.TypeMapper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.analyzer.AnalyzeExhaust; import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.NamespaceCodegen; import org.jetbrains.jet.di.InjectorForJetTypeMapper; -import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.java.JetFilesProvider; -import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; @@ -127,53 +123,42 @@ public class JetPositionManager implements PositionManager { } private Collection classNamesForPosition(final SourcePosition sourcePosition) { - final Collection names = new ArrayList(); ApplicationManager.getApplication().runReadAction(new Runnable() { @Override + @SuppressWarnings("unchecked") public void run() { - final JetFile file = (JetFile)sourcePosition.getFile(); - JetTypeMapper typeMapper = prepareTypeMapper(file); + final JetFile namespace = (JetFile)sourcePosition.getFile(); + final JetTypeMapper typeMapper = prepareTypeMapper(namespace); - PsiElement psiElement = PsiTreeUtil.getParentOfType(sourcePosition.getElementAt(), JetClassOrObject.class, JetFunctionLiteralExpression.class, JetNamedFunction.class); - if (psiElement == null) { - JetFile namespace = PsiTreeUtil.getParentOfType(sourcePosition.getElementAt(), JetFile.class); - if (namespace != null) { - names.add(NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(namespace)).getInternalName()); + PsiElement element = PsiTreeUtil.getParentOfType(sourcePosition.getElementAt(), JetClassOrObject.class, JetFunctionLiteralExpression.class, JetNamedFunction.class); + if (element instanceof JetClassOrObject) { + names.add(typeMapper.getJvmInternalName((JetClassOrObject)element)); + } + else if (element instanceof JetFunctionLiteralExpression) { + names.add(typeMapper.getClosureAnnotator().classNameForAnonymousClass((JetFunctionLiteralExpression)element).getInternalName()); + } + else if (element instanceof JetNamedFunction) { + PsiElement parent = PsiTreeUtil.getParentOfType(element, JetClassOrObject.class, JetFunctionLiteralExpression.class, JetNamedFunction.class); + if (parent instanceof JetClassOrObject) { + names.add(typeMapper.getJvmInternalName((JetClassOrObject)parent)); } - else { - names.add(NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(file)).getInternalName()); + else if (parent instanceof JetFunctionLiteralExpression || parent instanceof JetNamedFunction) { + names.add(typeMapper.getClosureAnnotator().classNameForAnonymousClass((JetElement)element).getInternalName()); } } - else { - if (psiElement instanceof JetClassOrObject) { - names.addAll(typeMapper.allJvmNames((JetClassOrObject) psiElement)); - } - else if(psiElement instanceof JetNamedFunction) { - if(psiElement.getParent() instanceof JetFile) { - JetFile namespace = PsiTreeUtil.getParentOfType(sourcePosition.getElementAt(), JetFile.class); - boolean multiFileNamespace = typeMapper.getClosureAnnotator().isMultiFileNamespace(JetPsiUtil.getFQName(namespace)); - if(multiFileNamespace) { - String name = namespace.getName(); - names.add(NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(namespace)).getInternalName() + "$src$" + name.substring(0,name.lastIndexOf('.'))); - } - else { - names.add(NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(namespace)).getInternalName()); - } - } - else { - JetFile namespace = PsiTreeUtil.getParentOfType(sourcePosition.getElementAt(), JetFile.class); - if (namespace != null) { - names.add(NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(namespace)).getInternalName()); - } - else { - names.add(NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(file)).getInternalName()); - } - } + + if (names.isEmpty()) { + FqName fqName = JetPsiUtil.getFQName(namespace); + boolean multiFileNamespace = typeMapper.getClosureAnnotator().isMultiFileNamespace(fqName); + String namespaceInternalName = NamespaceCodegen.getJVMClassNameForKotlinNs(fqName).getInternalName(); + if (multiFileNamespace) { + String name = namespace.getName(); + names.add(namespaceInternalName + "$src$" + name.substring(0, name.lastIndexOf('.'))); } else { - names.add(typeMapper.getClosureAnnotator().classNameForAnonymousClass((JetElement) psiElement).getInternalName()); + names.add(namespaceInternalName); } } } From 90c7683f3cf0fac0bde9521a2b6833bcb3b570e9 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 14 Aug 2012 19:28:27 +0400 Subject: [PATCH 17/36] classNamesForPosition always returns one class name --- .../plugin/debugger/JetPositionManager.java | 43 ++++++++----------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java b/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java index 4cbf8658088..b6de25a02a3 100644 --- a/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java +++ b/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java @@ -23,7 +23,7 @@ import com.intellij.debugger.engine.DebugProcess; import com.intellij.debugger.requests.ClassPrepareRequestor; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.util.Ref; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.search.FilenameIndex; @@ -114,16 +114,17 @@ public class JetPositionManager implements PositionManager { if (!(sourcePosition.getFile() instanceof JetFile)) { throw new NoDataException(); } - final Collection names = classNamesForPosition(sourcePosition); + String name = classNameForPosition(sourcePosition); List result = new ArrayList(); - for (String name : names) { + if (name != null) { result.addAll(myDebugProcess.getVirtualMachineProxy().classesByName(name)); } return result; } - private Collection classNamesForPosition(final SourcePosition sourcePosition) { - final Collection names = new ArrayList(); + @Nullable + private String classNameForPosition(final SourcePosition sourcePosition) { + final Ref result = Ref.create(); ApplicationManager.getApplication().runReadAction(new Runnable() { @Override @@ -134,37 +135,37 @@ public class JetPositionManager implements PositionManager { PsiElement element = PsiTreeUtil.getParentOfType(sourcePosition.getElementAt(), JetClassOrObject.class, JetFunctionLiteralExpression.class, JetNamedFunction.class); if (element instanceof JetClassOrObject) { - names.add(typeMapper.getJvmInternalName((JetClassOrObject)element)); + result.set(typeMapper.getJvmInternalName((JetClassOrObject) element)); } else if (element instanceof JetFunctionLiteralExpression) { - names.add(typeMapper.getClosureAnnotator().classNameForAnonymousClass((JetFunctionLiteralExpression)element).getInternalName()); + result.set(typeMapper.getClosureAnnotator().classNameForAnonymousClass((JetFunctionLiteralExpression)element).getInternalName()); } else if (element instanceof JetNamedFunction) { PsiElement parent = PsiTreeUtil.getParentOfType(element, JetClassOrObject.class, JetFunctionLiteralExpression.class, JetNamedFunction.class); if (parent instanceof JetClassOrObject) { - names.add(typeMapper.getJvmInternalName((JetClassOrObject)parent)); + result.set(typeMapper.getJvmInternalName((JetClassOrObject) parent)); } else if (parent instanceof JetFunctionLiteralExpression || parent instanceof JetNamedFunction) { - names.add(typeMapper.getClosureAnnotator().classNameForAnonymousClass((JetElement)element).getInternalName()); + result.set(typeMapper.getClosureAnnotator().classNameForAnonymousClass((JetElement)element).getInternalName()); } } - if (names.isEmpty()) { + if (result.isNull()) { FqName fqName = JetPsiUtil.getFQName(namespace); boolean multiFileNamespace = typeMapper.getClosureAnnotator().isMultiFileNamespace(fqName); String namespaceInternalName = NamespaceCodegen.getJVMClassNameForKotlinNs(fqName).getInternalName(); if (multiFileNamespace) { String name = namespace.getName(); - names.add(namespaceInternalName + "$src$" + name.substring(0, name.lastIndexOf('.'))); + result.set(namespaceInternalName + "$src$" + name.substring(0, name.lastIndexOf('.'))); } else { - names.add(namespaceInternalName); + result.set(namespaceInternalName); } } } }); - return names; + return result.get(); } private JetTypeMapper prepareTypeMapper(final JetFile file) { @@ -215,20 +216,10 @@ public class JetPositionManager implements PositionManager { if (!(sourcePosition.getFile() instanceof JetFile)) { throw new NoDataException(); } - final Collection classNames = classNamesForPosition(sourcePosition); - if (classNames.isEmpty()) { + final String className = classNameForPosition(sourcePosition); + if (className == null) { return null; } - final Iterator iterator = classNames.iterator(); - boolean wildcard = false; - String namePattern = iterator.next(); - while (iterator.hasNext()) { - namePattern = StringUtil.commonPrefix(namePattern, iterator.next()); - wildcard = true; - } - if (wildcard) { - namePattern += "*"; - } - return myDebugProcess.getRequestsManager().createClassPrepareRequest(classPrepareRequestor, namePattern.replace('/', '.')); + return myDebugProcess.getRequestsManager().createClassPrepareRequest(classPrepareRequestor, className.replace('/', '.')); } } From c38453f4abcfc4803525bc74a94b3fc2ae195c39 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 14 Aug 2012 22:08:16 +0400 Subject: [PATCH 18/36] Fix formatting --- .../jet/plugin/completion/JetClassCompletionContributor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetClassCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetClassCompletionContributor.java index 8f4eca746bd..72cd9dea57e 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetClassCompletionContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetClassCompletionContributor.java @@ -119,7 +119,7 @@ public class JetClassCompletionContributor extends CompletionContributor { for (JetClassOrObject classOrObject : classOrObjects) { if (classOrObject.getContainingFile().getOriginalFile().equals(aClass.getContainingFile())) { Collection classDescriptors = ResolveSessionUtils.getClassDescriptorsByFqName( - resolveSession,((JetLightClass) aClass).getFqName()); + resolveSession, ((JetLightClass) aClass).getFqName()); for (ClassDescriptor descriptor : classDescriptors) { consumer.consume(DescriptorLookupConverter.createLookupElement(resolveSession, context, descriptor)); } From 8472e77ccbd7c43e88f107015bcdd1f805e1ce25 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 14 Aug 2012 22:10:26 +0400 Subject: [PATCH 19/36] Remove hack with supressing "Virtual pointer hasn't been disposed" exception after detaching library. --- .../jet/completion/JetBasicCompletionTest.java | 13 ------------- .../plugin/importOptimizer/OptimizeImportsTest.java | 13 ------------- .../jet/plugin/quickfix/JetQuickFixTest.java | 12 ------------ 3 files changed, 38 deletions(-) diff --git a/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java b/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java index b3419421d1a..1a21c8beafc 100644 --- a/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java +++ b/idea/tests/org/jetbrains/jet/completion/JetBasicCompletionTest.java @@ -24,19 +24,6 @@ import java.io.File; * @author Nikolay.Krasko */ public class JetBasicCompletionTest extends JetCompletionTestBase { - - @Override - protected void tearDown() throws Exception { - try { - super.tearDown(); - } catch (RuntimeException exception) { - // TODO: Fix inability to free pointer for runtimejar in JetWithJdkAndRuntimeLightProjectDescriptor - if (!(exception.getMessage().contains("runtimejar") && exception.getMessage().contains("Virtual pointer hasn't been disposed"))) { - throw exception; - } - } - } - public void testAutoCastAfterIf() { doTest(); } diff --git a/idea/tests/org/jetbrains/jet/plugin/importOptimizer/OptimizeImportsTest.java b/idea/tests/org/jetbrains/jet/plugin/importOptimizer/OptimizeImportsTest.java index 58039bae515..cf926c0650f 100644 --- a/idea/tests/org/jetbrains/jet/plugin/importOptimizer/OptimizeImportsTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/importOptimizer/OptimizeImportsTest.java @@ -32,19 +32,6 @@ import java.io.File; * @author Nikolay Krasko */ public class OptimizeImportsTest extends LightCodeInsightTestCase { - - @Override - protected void tearDown() throws Exception { - try { - super.tearDown(); - } catch (RuntimeException exception) { - // TODO: Fix inability to free pointer for runtimejar in JetWithJdkAndRuntimeLightProjectDescriptor - if (!(exception.getMessage().contains("runtimejar") && exception.getMessage().contains("Virtual pointer hasn't been disposed"))) { - throw exception; - } - } - } - public void testAlreadyOptimized() throws Exception { doTest(); } diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/JetQuickFixTest.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/JetQuickFixTest.java index 47b28f2f05d..7865a2d0186 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/JetQuickFixTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/JetQuickFixTest.java @@ -67,18 +67,6 @@ public class JetQuickFixTest extends LightQuickFixTestCase { }; } - @Override - protected void tearDown() throws Exception { - try { - super.tearDown(); - } catch (RuntimeException exception) { - // TODO: Fix inability to free pointer for runtimejar in JetWithJdkAndRuntimeLightProjectDescriptor - if (!(exception.getMessage().contains("runtimejar") && exception.getMessage().contains("Virtual pointer hasn't been disposed"))) { - throw exception; - } - } - } - public static Test suite() { //setFilter(); //to launch only part of tests TestSuite suite = new TestSuite(); From f817b04f84ceb14895515765ba590ba4d0a2ea13 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 15 Aug 2012 11:27:45 +0400 Subject: [PATCH 20/36] Now IdeaWin*.dll libraries can be correctly loaded from bin directory so there's no need to copy them --- update_dependencies.xml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/update_dependencies.xml b/update_dependencies.xml index 7cd49c0e8a0..5b54d9474f2 100644 --- a/update_dependencies.xml +++ b/update_dependencies.xml @@ -185,13 +185,6 @@ - - - - - - - From 87a8e0a5dc5de2b024e47b154e0bfc0025d442b4 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Wed, 15 Aug 2012 10:44:33 +0300 Subject: [PATCH 21/36] enum classes are never inner --- .../jet/codegen/ClosureAnnotator.java | 41 ++++++++++++++----- compiler/testData/codegen/enum/inclassobj.kt | 15 +++++++ .../jetbrains/jet/codegen/EnumGenTest.java | 4 ++ 3 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 compiler/testData/codegen/enum/inclassobj.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java index 5dfd501ff89..9e1d91500ec 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java @@ -42,8 +42,9 @@ public class ClosureAnnotator { private final Map anonymousSubclassesCount = new HashMap(); private final Map classNameForScript = new HashMap(); private final Set scriptClassNames = new HashSet(); - private final Map classesForFunctions = new HashMap(); - private final Map enclosing = new HashMap(); + private final Map classesForFunctions = + new HashMap(); + private final Map enclosing = new HashMap(); private final MultiMap namespaceName2MultiNamespaceFiles = MultiMap.create(); private final MultiMap namespaceName2Files = MultiMap.create(); @@ -81,7 +82,10 @@ public class ClosureAnnotator { classDescriptor.initialize( false, Collections.emptyList(), - Collections.singleton((funDescriptor.getReceiverParameter().exists() ? JetStandardClasses.getReceiverFunction(arity) : JetStandardClasses.getFunction(arity)).getDefaultType()), JetScope.EMPTY, Collections.emptySet(), null); + Collections.singleton((funDescriptor.getReceiverParameter().exists() + ? JetStandardClasses.getReceiverFunction(arity) + : JetStandardClasses.getFunction(arity)).getDefaultType()), JetScope.EMPTY, + Collections.emptySet(), null); classesForFunctions.put(funDescriptor, classDescriptor); } return classDescriptor; @@ -169,7 +173,7 @@ public class ClosureAnnotator { ArrayList namespaceFiles = new ArrayList(); for (JetFile jetFile : entry.getValue()) { - ArrayList fileFunctions = new ArrayList(); + Collection fileFunctions = new ArrayList(); for (JetDeclaration declaration : jetFile.getDeclarations()) { if (declaration instanceof JetNamedFunction) { fileFunctions.add(declaration); @@ -181,7 +185,7 @@ public class ClosureAnnotator { } } - if(namespaceFiles.size() > 1) { + if (namespaceFiles.size() > 1) { for (JetFile namespaceFile : namespaceFiles) { namespaceName2MultiNamespaceFiles.putValue(entry.getKey(), namespaceFile); } @@ -214,7 +218,12 @@ public class ClosureAnnotator { } public boolean hasThis0(ClassDescriptor classDescriptor) { - if (DescriptorUtils.isClassObject(classDescriptor)) { return false; } + if (DescriptorUtils.isClassObject(classDescriptor)) { + return false; + } + if (classDescriptor.getKind() == ClassKind.ENUM_CLASS || classDescriptor.getKind() == ClassKind.ENUM_ENTRY) { + return false; + } ClassDescriptor other = enclosing.get(classDescriptor); return other != null; @@ -266,6 +275,7 @@ public class ClosureAnnotator { @Override public void visitJetFile(JetFile file) { if (file.isScript()) { + //noinspection ConstantConditions nameStack.push(classNameForScriptPsi(file.getScript()).getInternalName()); } else { @@ -279,6 +289,7 @@ public class ClosureAnnotator { public void visitClassObject(JetClassObject classObject) { JvmClassName name = recordClassObject(classObject); ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration()); + assert classDescriptor != null; recordEnclosing(classDescriptor); recordName(classDescriptor, name); classStack.push(classDescriptor); @@ -303,7 +314,9 @@ public class ClosureAnnotator { if (classDescriptor.getContainingDeclaration() instanceof NamespaceDescriptor) { nameStack.push(base.isEmpty() ? classDescriptor.getName().getName() : base + '/' + classDescriptor.getName()); } - else { nameStack.push(base + '$' + classDescriptor.getName()); } + else { + nameStack.push(base + '$' + classDescriptor.getName()); + } super.visitObjectDeclaration(declaration); nameStack.pop(); classStack.pop(); @@ -321,7 +334,9 @@ public class ClosureAnnotator { if (classDescriptor.getContainingDeclaration() instanceof NamespaceDescriptor) { nameStack.push(base.isEmpty() ? classDescriptor.getName().getName() : base + '/' + classDescriptor.getName()); } - else { nameStack.push(base + '$' + classDescriptor.getName()); } + else { + nameStack.push(base + '$' + classDescriptor.getName()); + } super.visitClass(klass); nameStack.pop(); classStack.pop(); @@ -347,7 +362,8 @@ public class ClosureAnnotator { @Override public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) { JvmClassName name = recordAnonymousClass(expression.getFunctionLiteral()); - FunctionDescriptor declarationDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, expression); + FunctionDescriptor declarationDescriptor = + (FunctionDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, expression); // working around a problem with shallow analysis if (declarationDescriptor == null) return; ClassDescriptor classDescriptor = classDescriptorForFunctionDescriptor(declarationDescriptor, name); @@ -368,7 +384,8 @@ public class ClosureAnnotator { @Override public void visitNamedFunction(JetNamedFunction function) { - FunctionDescriptor functionDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, function); + FunctionDescriptor functionDescriptor = + (FunctionDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, function); // working around a problem with shallow analysis if (functionDescriptor == null) return; DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration(); @@ -379,7 +396,9 @@ public class ClosureAnnotator { } else if (containingDeclaration instanceof NamespaceDescriptor) { String peek = nameStack.peek(); - if (peek.isEmpty()) { peek = "namespace"; } + if (peek.isEmpty()) { + peek = "namespace"; + } else { peek += "/namespace"; } diff --git a/compiler/testData/codegen/enum/inclassobj.kt b/compiler/testData/codegen/enum/inclassobj.kt new file mode 100644 index 00000000000..93a51f89657 --- /dev/null +++ b/compiler/testData/codegen/enum/inclassobj.kt @@ -0,0 +1,15 @@ +fun box() = if(Context.operatingSystemType == Context.OsType.OTHER) "OK" else "fail" + +public class Context +{ + class object + { + public enum class OsType { + LINUX; + OTHER + } + + public val operatingSystemType: OsType + get() = OsType.OTHER + } +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java index 5f973068657..be46d8de8cd 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java @@ -96,4 +96,8 @@ public class EnumGenTest extends CodegenTestCase { public void testValues() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { blackBoxFile("enum/valueof.kt"); } + + public void testInClassObj() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { + blackBoxFile("enum/inclassobj.kt"); + } } From fb72a4d1f220c3d7d1d681ae17b4e22e89fb51d1 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 15 Aug 2012 11:54:45 +0400 Subject: [PATCH 22/36] Formatting --- .../jet/lang/resolve/DescriptorResolver.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java index 90dac89c0e8..a670390735d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java @@ -1179,8 +1179,18 @@ public class DescriptorResolver { return mutableClassDescriptor.getDefaultType(); } }); - ValueParameterDescriptorImpl parameterDescriptor = new ValueParameterDescriptorImpl(values,0,Collections.emptyList(),Name.identifier("value"),false,JetStandardLibrary.getInstance().getStringType(),false,null); - values.initialize(null, classReceiver, Collections.emptyList(),Arrays.asList(parameterDescriptor), + ValueParameterDescriptor parameterDescriptor = new ValueParameterDescriptorImpl( + values, + 0, + Collections.emptyList(), + Name.identifier("value"), + false, + JetStandardLibrary.getInstance().getStringType(), + false, + null); + values.initialize(null, classReceiver, + Collections.emptyList(), + Collections.singletonList(parameterDescriptor), type, Modality.FINAL, Visibilities.PUBLIC, false); return values; From 22f8ca4bee54f47f48a8bf3358f9ba9fd38a9322 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 15 Aug 2012 12:29:07 +0400 Subject: [PATCH 23/36] resolveSupertypes() refactored * ClassDescriptor passed explicitly, psi-based checks and trace reading eliminated * some clarifying renames/extractions made --- .../jet/lang/resolve/DescriptorResolver.java | 48 ++++++++++--------- .../resolve/lazy/LazyClassDescriptor.java | 2 +- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java index a670390735d..3ca95df924e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java @@ -48,7 +48,6 @@ import javax.inject.Inject; import java.util.*; import static org.jetbrains.jet.lang.diagnostics.Errors.*; -import static org.jetbrains.jet.lang.resolve.BindingContext.CLASS; import static org.jetbrains.jet.lang.resolve.BindingContext.CONSTRUCTOR; /** @@ -112,43 +111,46 @@ public class DescriptorResolver { @NotNull MutableClassDescriptor descriptor, BindingTrace trace ) { - for (JetType supertype : resolveSupertypes(descriptor.getScopeForSupertypeResolution(), jetClass, trace)) { + for (JetType supertype : resolveSupertypes(descriptor.getScopeForSupertypeResolution(), descriptor, jetClass, trace)) { descriptor.addSupertype(supertype); } } - public List resolveSupertypes(@NotNull JetScope scope, @NotNull JetClassOrObject jetClass, BindingTrace trace) { - List result = Lists.newArrayList(); + public List resolveSupertypes( + @NotNull JetScope scope, + @NotNull ClassDescriptor classDescriptor, + @NotNull JetClassOrObject jetClass, + BindingTrace trace + ) { + List supertypes = Lists.newArrayList(); List delegationSpecifiers = jetClass.getDelegationSpecifiers(); - boolean isEnum = jetClass instanceof JetClass && ((JetClass) jetClass).hasModifier(JetTokens.ENUM_KEYWORD); + boolean isEnum = classDescriptor.getKind() == ClassKind.ENUM_CLASS; if (delegationSpecifiers.isEmpty()) { if (!isEnum) { - result.add(getDefaultSupertype(jetClass, trace)); + supertypes.add(getDefaultSupertype(jetClass, trace)); } } else { - Collection supertypes = resolveDelegationSpecifiers( + Collection declaredSupertypes = resolveDelegationSpecifiers( scope, delegationSpecifiers, typeResolver, trace, false); - for (JetType supertype : supertypes) { - result.add(supertype); + supertypes.addAll(declaredSupertypes); + } + if (isEnum && !containsClass(supertypes)) { + supertypes.add(0, JetStandardLibrary.getInstance().getEnumType(classDescriptor.getDefaultType())); + } + return supertypes; + } + + private boolean containsClass(Collection result) { + for (JetType type : result) { + ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); + if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() != ClassKind.TRAIT) { + return true; } } - if (isEnum) { - boolean hasSuper = false; - for (JetType type : result) { - ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); - if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() != ClassKind.TRAIT) { - hasSuper = true; - } - } - if (!hasSuper) { - ClassDescriptor classDescriptor = trace.getBindingContext().get(CLASS, jetClass); - result.add(0, JetStandardLibrary.getInstance().getEnumType(classDescriptor.getDefaultType())); - } - } - return result; + return false; } private JetType getDefaultSupertype(JetClassOrObject jetClass, BindingTrace trace) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java index 17b0f7e4865..42fdd8f6554 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java @@ -340,7 +340,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes else { List allSupertypes = resolveSession.getInjector().getDescriptorResolver() .resolveSupertypes(getScopeForClassHeaderResolution(), - classOrObject, + LazyClassDescriptor.this, classOrObject, resolveSession.getTrace()); List validSupertypes = Lists.newArrayList(Collections2.filter(allSupertypes, VALID_SUPERTYPE)); this.supertypes = validSupertypes; From 29048663564457545bf7c8e16c51349a9257ce0e Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 15 Aug 2012 12:31:05 +0400 Subject: [PATCH 24/36] Useless final removed --- .../jet/lang/resolve/TypeHierarchyResolver.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index 126c06e878e..43562576806 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -24,19 +24,18 @@ import com.intellij.psi.PsiNameIdentifierOwner; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WriteThroughScope; -import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver; -import org.jetbrains.jet.lang.types.*; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.SubstitutionUtils; +import org.jetbrains.jet.lang.types.TypeConstructor; +import org.jetbrains.jet.lang.types.TypeProjection; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; import org.jetbrains.jet.lexer.JetTokens; -import org.jetbrains.jet.util.lazy.LazyValue; import javax.inject.Inject; import java.util.*; @@ -288,7 +287,7 @@ public class TypeHierarchyResolver { } } - private void createClassObjectForEnumClass(JetClass klass, final MutableClassDescriptor mutableClassDescriptor) { + private void createClassObjectForEnumClass(JetClass klass, MutableClassDescriptor mutableClassDescriptor) { if (klass.hasModifier(JetTokens.ENUM_KEYWORD)) { MutableClassDescriptor classObjectDescriptor = new MutableClassDescriptor( mutableClassDescriptor, outerScope, ClassKind.OBJECT, From 5ee995b8cbdefacb18241ec503881b1bf72e6f54 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 15 Aug 2012 13:02:12 +0400 Subject: [PATCH 25/36] Type fixed --- .../jet/lang/resolve/lazy/LazyClassDescriptor.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java index 42fdd8f6554..18b54c00f83 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java @@ -48,7 +48,7 @@ import java.util.*; */ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDescriptorFromSource { - private static final Predicate ONLY_ENUM_ENTIRES = Predicates.instanceOf(JetEnumEntry.class); + private static final Predicate ONLY_ENUM_ENTRIES = Predicates.instanceOf(JetEnumEntry.class); private static final Predicate VALID_SUPERTYPE = new Predicate() { @Override public boolean apply(JetType type) { @@ -396,11 +396,11 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes } private static JetClassLikeInfo noEnumEntries(JetClassLikeInfo classLikeInfo) { - return new FilteringClassLikeInfo(classLikeInfo, Predicates.not(ONLY_ENUM_ENTIRES)); + return new FilteringClassLikeInfo(classLikeInfo, Predicates.not(ONLY_ENUM_ENTRIES)); } private static JetClassLikeInfo onlyEnumEntries(JetClassLikeInfo classLikeInfo) { - return new FilteringClassLikeInfo(classLikeInfo, ONLY_ENUM_ENTIRES) { + return new FilteringClassLikeInfo(classLikeInfo, ONLY_ENUM_ENTRIES) { @Override public JetClassOrObject getCorrespondingClassOrObject() { return null; From 24b83dd8f7ccac87dc42626062cb2b170b1bc5be Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 15 Aug 2012 13:34:18 +0400 Subject: [PATCH 26/36] Getting rid of unneeded parameters + constants introduced --- .../jet/lang/resolve/DescriptorResolver.java | 24 ++++++++++++------- .../lang/resolve/TypeHierarchyResolver.java | 6 ++--- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java index 3ca95df924e..e638f798334 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java @@ -54,6 +54,9 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.CONSTRUCTOR; * @author abreslav */ public class DescriptorResolver { + public static final Name VALUE_OF_METHOD_NAME = Name.identifier("valueOf"); + public static final Name VALUES_METHOD_NAME = Name.identifier("values"); + @NotNull private TypeResolver typeResolver; @NotNull @@ -1142,43 +1145,46 @@ public class DescriptorResolver { } public static SimpleFunctionDescriptor createEnumClassObjectValuesMethod( - final ClassDescriptor mutableClassDescriptor, - ClassDescriptor classObjectDescriptor, + final ClassDescriptor enumClassDescriptor, BindingTrace trace ) { + ClassDescriptor classObjectDescriptor = enumClassDescriptor.getClassObjectDescriptor(); + assert classObjectDescriptor != null : "Enum class has no class object"; List annotations = Collections.emptyList(); SimpleFunctionDescriptorImpl values = new SimpleFunctionDescriptorImpl(classObjectDescriptor, annotations, - Name.identifier("values"), + VALUES_METHOD_NAME, CallableMemberDescriptor.Kind.DECLARATION); ClassReceiver classReceiver = new ClassReceiver(classObjectDescriptor); JetType type = DeferredType.create(trace, new LazyValue() { @Override protected JetType compute() { - return JetStandardLibrary.getInstance().getArrayType(mutableClassDescriptor.getDefaultType()); + return JetStandardLibrary.getInstance().getArrayType(enumClassDescriptor.getDefaultType()); } }); - values.initialize(null, classReceiver, Collections.emptyList(),Collections.emptyList(), + values.initialize(null, classReceiver, Collections.emptyList(), + Collections.emptyList(), type, Modality.FINAL, Visibilities.PUBLIC, false); return values; } public static SimpleFunctionDescriptor createEnumClassObjectValueOfMethod( - final ClassDescriptor mutableClassDescriptor, - ClassDescriptor classObjectDescriptor, + final ClassDescriptor enumClassDescriptor, BindingTrace trace ) { + ClassDescriptor classObjectDescriptor = enumClassDescriptor.getClassObjectDescriptor(); + assert classObjectDescriptor != null : "Enum class has no class object"; List annotations = Collections.emptyList(); SimpleFunctionDescriptorImpl values = new SimpleFunctionDescriptorImpl(classObjectDescriptor, annotations, - Name.identifier("valueOf"), + VALUE_OF_METHOD_NAME, CallableMemberDescriptor.Kind.DECLARATION); ClassReceiver classReceiver = new ClassReceiver(classObjectDescriptor); JetType type = DeferredType.create(trace, new LazyValue() { @Override protected JetType compute() { - return mutableClassDescriptor.getDefaultType(); + return enumClassDescriptor.getDefaultType(); } }); ValueParameterDescriptor parameterDescriptor = new ValueParameterDescriptorImpl( diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index 43562576806..6e071bb041f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -292,6 +292,7 @@ public class TypeHierarchyResolver { MutableClassDescriptor classObjectDescriptor = new MutableClassDescriptor( mutableClassDescriptor, outerScope, ClassKind.OBJECT, Name.special("")); + mutableClassDescriptor.getBuilder().setClassObjectDescriptor(classObjectDescriptor); classObjectDescriptor.setModality(Modality.FINAL); classObjectDescriptor.setVisibility(DescriptorResolver.resolveVisibilityFromModifiers(klass.getModifierList())); classObjectDescriptor.setTypeParameterDescriptors(new ArrayList(0)); @@ -299,9 +300,8 @@ public class TypeHierarchyResolver { ConstructorDescriptorImpl primaryConstructorForObject = createPrimaryConstructorForObject(null, classObjectDescriptor); primaryConstructorForObject.setReturnType(classObjectDescriptor.getDefaultType()); - classObjectDescriptor.getBuilder().addFunctionDescriptor(DescriptorResolver.createEnumClassObjectValuesMethod(mutableClassDescriptor, classObjectDescriptor, trace)); - classObjectDescriptor.getBuilder().addFunctionDescriptor(DescriptorResolver.createEnumClassObjectValueOfMethod(mutableClassDescriptor, classObjectDescriptor,trace)); - mutableClassDescriptor.getBuilder().setClassObjectDescriptor(classObjectDescriptor); + classObjectDescriptor.getBuilder().addFunctionDescriptor(DescriptorResolver.createEnumClassObjectValuesMethod(mutableClassDescriptor, trace)); + classObjectDescriptor.getBuilder().addFunctionDescriptor(DescriptorResolver.createEnumClassObjectValueOfMethod(mutableClassDescriptor, trace)); } } From e7e7188da10d08630fe5d6fe8764b2012d3563ea Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 15 Aug 2012 13:34:51 +0400 Subject: [PATCH 27/36] LR: values() and valueOf() created properly for enums' class objects --- .../resolve/lazy/LazyClassMemberScope.java | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassMemberScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassMemberScope.java index aa63232f33a..22ac9394235 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassMemberScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassMemberScope.java @@ -17,7 +17,6 @@ package org.jetbrains.jet.lang.resolve.lazy; import com.google.common.collect.Lists; -import com.google.common.collect.Sets; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -139,26 +138,26 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope result, @NotNull Name name) { DeclarationDescriptor containingDeclaration = thisDescriptor.getContainingDeclaration(); - if(containingDeclaration instanceof ClassDescriptor) { - ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration; - if(classDescriptor.getKind() == ClassKind.ENUM_CLASS) { - if(classDescriptor.getClassObjectDescriptor() == thisDescriptor) { - SimpleFunctionDescriptor valuesMethod = DescriptorResolver - .createEnumClassObjectValuesMethod(classDescriptor, thisDescriptor, resolveSession.getTrace()); - functionDescriptors.put(valuesMethod.getName(), Collections.singleton(valuesMethod)); - allDescriptors.add(valuesMethod); - SimpleFunctionDescriptor valueOfMethod = DescriptorResolver.createEnumClassObjectValueOfMethod(classDescriptor, - thisDescriptor, - resolveSession.getTrace()); - functionDescriptors.put(valueOfMethod.getName(), Collections.singleton(valueOfMethod)); - allDescriptors.add(valueOfMethod); - } - } + if (!(containingDeclaration instanceof ClassDescriptor)) return; + ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration; + if (classDescriptor.getClassObjectDescriptor() != thisDescriptor) return; + if (classDescriptor.getKind() != ClassKind.ENUM_CLASS) return; + + if (name.equals(DescriptorResolver.VALUES_METHOD_NAME)) { + SimpleFunctionDescriptor valuesMethod = DescriptorResolver + .createEnumClassObjectValuesMethod(classDescriptor, resolveSession.getTrace()); + result.add(valuesMethod); + } + else if (name.equals(DescriptorResolver.VALUE_OF_METHOD_NAME)) { + SimpleFunctionDescriptor valueOfMethod = DescriptorResolver.createEnumClassObjectValueOfMethod(classDescriptor, + resolveSession.getTrace()); + result.add(valueOfMethod); } } @@ -248,7 +247,8 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope Date: Wed, 15 Aug 2012 13:39:20 +0400 Subject: [PATCH 28/36] Extract method for clarification --- .../resolve/lazy/LazyClassMemberScope.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassMemberScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassMemberScope.java index 22ac9394235..9bf1da1269a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassMemberScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassMemberScope.java @@ -143,11 +143,9 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope result, @NotNull Name name) { - DeclarationDescriptor containingDeclaration = thisDescriptor.getContainingDeclaration(); - if (!(containingDeclaration instanceof ClassDescriptor)) return; - ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration; - if (classDescriptor.getClassObjectDescriptor() != thisDescriptor) return; - if (classDescriptor.getKind() != ClassKind.ENUM_CLASS) return; + if (!isEnumClassObject()) return; + + ClassDescriptor classDescriptor = (ClassDescriptor) thisDescriptor.getContainingDeclaration(); if (name.equals(DescriptorResolver.VALUES_METHOD_NAME)) { SimpleFunctionDescriptor valuesMethod = DescriptorResolver @@ -155,12 +153,21 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope getProperties(@NotNull Name name) { From 00305ba9201424526197e6327587283423427d61 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 15 Aug 2012 16:15:04 +0400 Subject: [PATCH 29/36] Fixing interdependency between delegation and fake overrides Main changes sit in OverrideResolver::generateOverridesAndDelegationInAClass() Now fake overrides AND delegation are generated for supertypes before any processing is done for subclasses. --- .../di/InjectorForTopDownAnalyzerForJvm.java | 7 --- .../di/InjectorForTopDownAnalyzerBasic.java | 7 --- .../jet/lang/resolve/DeclarationsChecker.java | 1 + .../jet/lang/resolve/DelegationResolver.java | 38 ++---------- .../jet/lang/resolve/OverrideResolver.java | 58 +++++++++---------- .../jet/lang/resolve/TopDownAnalyzer.java | 8 --- .../Delegation_ScopeInitializationOrder.kt | 11 ++++ .../checkers/AbstractJetDiagnosticsTest.java | 12 +++- .../checkers/JetDiagnosticsTestGenerated.java | 13 +++-- .../di/InjectorForTopDownAnalyzerForJs.java | 7 --- 10 files changed, 62 insertions(+), 100 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/Delegation_ScopeInitializationOrder.kt diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java index c4905da5c37..1473e120fac 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java @@ -42,7 +42,6 @@ import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver; import org.jetbrains.jet.lang.resolve.calls.OverloadingConflictResolver; import org.jetbrains.jet.lang.resolve.ImportsResolver; import org.jetbrains.jet.lang.resolve.ScriptHeaderResolver; -import org.jetbrains.jet.lang.resolve.DelegationResolver; import org.jetbrains.jet.lang.resolve.OverloadResolver; import org.jetbrains.jet.lang.resolve.OverrideResolver; import org.jetbrains.jet.lang.resolve.TypeHierarchyResolver; @@ -80,7 +79,6 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly private OverloadingConflictResolver overloadingConflictResolver; private ImportsResolver importsResolver; private ScriptHeaderResolver scriptHeaderResolver; - private DelegationResolver delegationResolver; private OverloadResolver overloadResolver; private OverrideResolver overrideResolver; private TypeHierarchyResolver typeHierarchyResolver; @@ -120,7 +118,6 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly this.overloadingConflictResolver = new OverloadingConflictResolver(); this.importsResolver = new ImportsResolver(); this.scriptHeaderResolver = new ScriptHeaderResolver(); - this.delegationResolver = new DelegationResolver(); this.overloadResolver = new OverloadResolver(); this.overrideResolver = new OverrideResolver(); this.typeHierarchyResolver = new TypeHierarchyResolver(); @@ -132,7 +129,6 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly this.topDownAnalyzer.setBodyResolver(bodyResolver); this.topDownAnalyzer.setContext(topDownAnalysisContext); this.topDownAnalyzer.setDeclarationResolver(declarationResolver); - this.topDownAnalyzer.setDelegationResolver(delegationResolver); this.topDownAnalyzer.setModuleDescriptor(moduleDescriptor); this.topDownAnalyzer.setNamespaceFactory(namespaceFactory); this.topDownAnalyzer.setOverloadResolver(overloadResolver); @@ -214,9 +210,6 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly scriptHeaderResolver.setTopDownAnalysisParameters(topDownAnalysisParameters); scriptHeaderResolver.setTrace(bindingTrace); - delegationResolver.setContext(topDownAnalysisContext); - delegationResolver.setTrace(bindingTrace); - overloadResolver.setContext(topDownAnalysisContext); overloadResolver.setTrace(bindingTrace); diff --git a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerBasic.java b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerBasic.java index 4c29dd3d5ae..fc1fff391d0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerBasic.java +++ b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerBasic.java @@ -39,7 +39,6 @@ import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver; import org.jetbrains.jet.lang.resolve.calls.OverloadingConflictResolver; import org.jetbrains.jet.lang.resolve.ImportsResolver; import org.jetbrains.jet.lang.resolve.ScriptHeaderResolver; -import org.jetbrains.jet.lang.resolve.DelegationResolver; import org.jetbrains.jet.lang.resolve.OverloadResolver; import org.jetbrains.jet.lang.resolve.OverrideResolver; import org.jetbrains.jet.lang.resolve.TypeHierarchyResolver; @@ -72,7 +71,6 @@ public class InjectorForTopDownAnalyzerBasic { private OverloadingConflictResolver overloadingConflictResolver; private ImportsResolver importsResolver; private ScriptHeaderResolver scriptHeaderResolver; - private DelegationResolver delegationResolver; private OverloadResolver overloadResolver; private OverrideResolver overrideResolver; private TypeHierarchyResolver typeHierarchyResolver; @@ -107,7 +105,6 @@ public class InjectorForTopDownAnalyzerBasic { this.overloadingConflictResolver = new OverloadingConflictResolver(); this.importsResolver = new ImportsResolver(); this.scriptHeaderResolver = new ScriptHeaderResolver(); - this.delegationResolver = new DelegationResolver(); this.overloadResolver = new OverloadResolver(); this.overrideResolver = new OverrideResolver(); this.typeHierarchyResolver = new TypeHierarchyResolver(); @@ -116,7 +113,6 @@ public class InjectorForTopDownAnalyzerBasic { this.topDownAnalyzer.setBodyResolver(bodyResolver); this.topDownAnalyzer.setContext(topDownAnalysisContext); this.topDownAnalyzer.setDeclarationResolver(declarationResolver); - this.topDownAnalyzer.setDelegationResolver(delegationResolver); this.topDownAnalyzer.setModuleDescriptor(moduleDescriptor); this.topDownAnalyzer.setNamespaceFactory(namespaceFactory); this.topDownAnalyzer.setOverloadResolver(overloadResolver); @@ -185,9 +181,6 @@ public class InjectorForTopDownAnalyzerBasic { scriptHeaderResolver.setTopDownAnalysisParameters(topDownAnalysisParameters); scriptHeaderResolver.setTrace(bindingTrace); - delegationResolver.setContext(topDownAnalysisContext); - delegationResolver.setTrace(bindingTrace); - overloadResolver.setContext(topDownAnalysisContext); overloadResolver.setTrace(bindingTrace); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java index 87653d27d09..8a2da3f505d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java @@ -122,6 +122,7 @@ public class DeclarationsChecker { private void checkOpenMembers(MutableClassDescriptor classDescriptor) { for (CallableMemberDescriptor memberDescriptor : classDescriptor.getDeclaredCallableMembers()) { + if (memberDescriptor.getKind() != CallableMemberDescriptor.Kind.DECLARATION) continue; JetNamedDeclaration member = (JetNamedDeclaration) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), memberDescriptor); if (member != null && classDescriptor.getModality() == Modality.FINAL && member.hasModifier(JetTokens.OPEN_KEYWORD)) { trace.report(NON_FINAL_MEMBER_IN_FINAL_CLASS.on(member)); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DelegationResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DelegationResolver.java index 31fcbf2f4d2..7cd54fd292e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DelegationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DelegationResolver.java @@ -21,49 +21,21 @@ import com.google.common.collect.Collections2; import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.psi.JetClassOrObject; +import org.jetbrains.jet.lang.psi.JetDelegationSpecifier; +import org.jetbrains.jet.lang.psi.JetDelegatorByExpressionSpecifier; import org.jetbrains.jet.lang.types.JetType; -import javax.inject.Inject; import java.util.Collection; -import java.util.Map; /** * @author abreslav */ public class DelegationResolver { - @NotNull - private TopDownAnalysisContext context; - @NotNull - private BindingTrace trace; + private DelegationResolver() {} - @Inject - public void setContext(@NotNull TopDownAnalysisContext context) { - this.context = context; - } - - @Inject - public void setTrace(@NotNull BindingTrace trace) { - this.trace = trace; - } - - - - public void process() { - addDelegatedMembers(); - } - - private void addDelegatedMembers() { - for (Map.Entry entry : context.getClasses().entrySet()) { - addDelegatedMembers(entry.getKey(), entry.getValue()); - } - for (Map.Entry entry : context.getObjects().entrySet()) { - addDelegatedMembers(entry.getKey(), entry.getValue()); - } - } - - private void addDelegatedMembers(JetClassOrObject jetClass, MutableClassDescriptor classDescriptor) { + public static void addDelegatedMembers(@NotNull BindingTrace trace, @NotNull JetClassOrObject jetClass, @NotNull MutableClassDescriptor classDescriptor) { for (JetDelegationSpecifier delegationSpecifier : jetClass.getDelegationSpecifiers()) { if (delegationSpecifier instanceof JetDelegatorByExpressionSpecifier) { JetDelegatorByExpressionSpecifier specifier = (JetDelegatorByExpressionSpecifier) delegationSpecifier; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java index 3f446cbed43..37fbbedce25 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java @@ -72,7 +72,7 @@ public class OverrideResolver { public void process() { //all created fake descriptors are stored to resolve visibility on them later - generateOverrides(); + generateOverridesAndDelegation(); checkVisibility(); checkOverrides(); @@ -82,7 +82,7 @@ public class OverrideResolver { /** * Generate fake overrides and add overridden descriptors to existing descriptors. */ - private void generateOverrides() { + private void generateOverridesAndDelegation() { Set ourClasses = new HashSet(); ourClasses.addAll(context.getClasses().values()); ourClasses.addAll(context.getObjects().values()); @@ -90,33 +90,34 @@ public class OverrideResolver { Set processed = new HashSet(); for (MutableClassDescriptor clazz : ourClasses) { - generateOverridesInAClass(clazz, processed, ourClasses); + generateOverridesAndDelegationInAClass(clazz, processed, ourClasses); } } - private void generateOverridesInAClass(@NotNull final MutableClassDescriptor classDescriptor, + private void generateOverridesAndDelegationInAClass( + @NotNull final MutableClassDescriptor classDescriptor, @NotNull Set processed, - @NotNull Set ourClasses) { + @NotNull Set classesBeingAnalyzed + // to filter out classes such as stdlib and others that come from dependencies + ) { if (!processed.add(classDescriptor)) { return; } - // avoid processing stdlib classes twice - if (!ourClasses.contains(classDescriptor)) { - return; - } - for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) { ClassDescriptor superclass = (ClassDescriptor) supertype.getConstructor().getDeclarationDescriptor(); - if (superclass instanceof MutableClassDescriptor) { - generateOverridesInAClass((MutableClassDescriptor) superclass, processed, ourClasses); + if (superclass instanceof MutableClassDescriptor && classesBeingAnalyzed.contains(superclass)) { + generateOverridesAndDelegationInAClass((MutableClassDescriptor) superclass, processed, classesBeingAnalyzed); } } - doGenerateOverridesInAClass(classDescriptor); + PsiElement declaration = BindingContextUtils.classDescriptorToDeclaration(trace.getBindingContext(), classDescriptor); + DelegationResolver.addDelegatedMembers(trace, (JetClassOrObject) declaration, classDescriptor); + + generateOverridesInAClass(classDescriptor); } - private void doGenerateOverridesInAClass(final MutableClassDescriptor classDescriptor) { + private void generateOverridesInAClass(final MutableClassDescriptor classDescriptor) { List membersFromSupertypes = getCallableMembersFromSupertypes(classDescriptor); MultiMap membersFromSupertypesByName = groupDescriptorsByName(membersFromSupertypes); @@ -160,7 +161,7 @@ public class OverrideResolver { } for (CallableMemberDescriptor memberDescriptor : classDescriptor.getAllCallableMembers()) { JetDeclaration declaration = null; - if (memberDescriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { + if (memberDescriptor.getKind() == CallableMemberDescriptor.Kind.DECLARATION) { PsiElement element = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), memberDescriptor); if (element instanceof JetDeclaration) { declaration = (JetDeclaration) element; @@ -453,21 +454,20 @@ public class OverrideResolver { } private void checkOverrideForMember(@NotNull CallableMemberDescriptor declared) { + if (declared.getKind() != CallableMemberDescriptor.Kind.DECLARATION) { + return; + } + JetNamedDeclaration member = (JetNamedDeclaration) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), declared); if (member == null) { if (declared.getKind() != CallableMemberDescriptor.Kind.DELEGATION) { throw new IllegalStateException( - "decriptor is not resolved to declaration" + - " and it is not delegate: " + declared + ", DELEGATED: " + - (declared.getKind() == CallableMemberDescriptor.Kind.DELEGATION)); + "descriptor is not resolved to declaration" + + " and it is not delegate: " + declared); } return; } - if (declared.getKind() != CallableMemberDescriptor.Kind.DECLARATION) { - return; - } - JetModifierList modifierList = member.getModifierList(); ASTNode overrideNode = modifierList != null ? modifierList.getModifierNode(JetTokens.OVERRIDE_KEYWORD) : null; boolean hasOverrideModifier = overrideNode != null; @@ -549,8 +549,8 @@ public class OverrideResolver { } private void checkOverridesForParameters(CallableMemberDescriptor declared) { - boolean fakeOverride = declared.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE; - if (!fakeOverride) { + boolean noDeclaration = declared.getKind() != CallableMemberDescriptor.Kind.DECLARATION; + if (!noDeclaration) { // No check if the function is not marked as 'override' JetModifierListOwner declaration = (JetModifierListOwner) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), declared); @@ -566,13 +566,13 @@ public class OverrideResolver { // b) p1 must have the same name as p2 for (ValueParameterDescriptor parameterFromSubclass : declared.getValueParameters()) { JetParameter parameter = - fakeOverride ? null : + noDeclaration ? null : (JetParameter) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), parameterFromSubclass); - JetClassOrObject classElement = fakeOverride ? (JetClassOrObject) BindingContextUtils + JetClassOrObject classElement = noDeclaration ? (JetClassOrObject) BindingContextUtils .descriptorToDeclaration(trace.getBindingContext(), declared.getContainingDeclaration()) : null; - if (parameterFromSubclass.declaresDefaultValue() && !fakeOverride) { + if (parameterFromSubclass.declaresDefaultValue() && !noDeclaration) { trace.report(DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE.on(parameter)); } @@ -583,7 +583,7 @@ public class OverrideResolver { superWithDefault = true; } else { - if (fakeOverride) { + if (noDeclaration) { trace.report(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE.on(classElement, parameterFromSubclass)); } else { @@ -594,7 +594,7 @@ public class OverrideResolver { } if (!parameterFromSuperclass.getName().equals(parameterFromSubclass.getName())) { - if (fakeOverride) { + if (noDeclaration) { trace.report(DIFFERENT_NAMES_FOR_THE_SAME_PARAMETER_IN_SUPERTYPES.on(classElement, declared.getOverriddenDescriptors(), parameterFromSuperclass.getIndex() + 1)); } else { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java index 744b1df4a88..6fb20e791bf 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java @@ -47,8 +47,6 @@ public class TopDownAnalyzer { @NotNull private TypeHierarchyResolver typeHierarchyResolver; @NotNull - private DelegationResolver delegationResolver; - @NotNull private OverrideResolver overrideResolver; @NotNull private OverloadResolver overloadResolver; @@ -75,11 +73,6 @@ public class TopDownAnalyzer { this.typeHierarchyResolver = typeHierarchyResolver; } - @Inject - public void setDelegationResolver(@NotNull DelegationResolver delegationResolver) { - this.delegationResolver = delegationResolver; - } - @Inject public void setOverrideResolver(@NotNull OverrideResolver overrideResolver) { this.overrideResolver = overrideResolver; @@ -131,7 +124,6 @@ public class TopDownAnalyzer { typeHierarchyResolver.process(outerScope, owner, declarations); declarationResolver.process(outerScope); - delegationResolver.process(); overrideResolver.process(); lockScopes(); diff --git a/compiler/testData/diagnostics/tests/Delegation_ScopeInitializationOrder.kt b/compiler/testData/diagnostics/tests/Delegation_ScopeInitializationOrder.kt new file mode 100644 index 00000000000..d1e51af531a --- /dev/null +++ b/compiler/testData/diagnostics/tests/Delegation_ScopeInitializationOrder.kt @@ -0,0 +1,11 @@ +class D(b: B) : C(b) +trait A { + fun foo() {} +} + +trait B : A {} + +class C(b : B) : B by b { + +} + diff --git a/compiler/tests/org/jetbrains/jet/checkers/AbstractJetDiagnosticsTest.java b/compiler/tests/org/jetbrains/jet/checkers/AbstractJetDiagnosticsTest.java index b613cc0fb46..17e64966968 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/AbstractJetDiagnosticsTest.java +++ b/compiler/tests/org/jetbrains/jet/checkers/AbstractJetDiagnosticsTest.java @@ -52,9 +52,15 @@ public abstract class AbstractJetDiagnosticsTest extends JetLiteFixture { catch (IOException e) { throw ExceptionUtils.rethrow(e); } - return new JetCoreEnvironment(getTestRootDisposable(), CompileCompilerDependenciesTest.compilerConfigurationForTests( - ConfigurationKind.JDK_AND_ANNOTATIONS, TestJdkKind.MOCK_JDK, JetTestUtils.getAnnotationsJar(), - javaFilesDir)); + return new JetCoreEnvironment( + getTestRootDisposable(), + CompileCompilerDependenciesTest.compilerConfigurationForTests( + ConfigurationKind.JDK_AND_ANNOTATIONS, + TestJdkKind.MOCK_JDK, + JetTestUtils.getAnnotationsJar(), + javaFilesDir + ) + ); } private static boolean writeJavaFile(@NotNull String fileName, @NotNull String content, @NotNull File javaFilesDir) { diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 8e68fcb6584..bbf58bad4fd 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -15,15 +15,12 @@ */ package org.jetbrains.jet.checkers; -import junit.framework.Assert; import junit.framework.Test; import junit.framework.TestSuite; - -import java.io.File; import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.test.TestMetadata; -import org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve; +import java.io.File; /** This class is generated by {@link org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve}. DO NOT MODIFY MANUALLY */ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEagerResolve { @@ -180,8 +177,12 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage @TestMetadata("DelegationNotTotrait.kt") public void testDelegationNotTotrait() throws Exception { - // todo FIXME: enable this test - //doTest("compiler/testData/diagnostics/tests/DelegationNotTotrait.kt"); + doTest("compiler/testData/diagnostics/tests/DelegationNotTotrait.kt"); + } + + @TestMetadata("Delegation_ScopeInitializationOrder.kt") + public void testDelegation_ScopeInitializationOrder() throws Exception { + doTest("compiler/testData/diagnostics/tests/Delegation_ScopeInitializationOrder.kt"); } @TestMetadata("DiamondFunction.kt") diff --git a/js/js.translator/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJs.java b/js/js.translator/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJs.java index 00e2a1badac..459380b1bea 100644 --- a/js/js.translator/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJs.java +++ b/js/js.translator/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJs.java @@ -39,7 +39,6 @@ import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver; import org.jetbrains.jet.lang.resolve.calls.OverloadingConflictResolver; import org.jetbrains.jet.lang.resolve.ImportsResolver; import org.jetbrains.jet.lang.resolve.ScriptHeaderResolver; -import org.jetbrains.jet.lang.resolve.DelegationResolver; import org.jetbrains.jet.lang.resolve.OverloadResolver; import org.jetbrains.jet.lang.resolve.OverrideResolver; import org.jetbrains.jet.lang.resolve.TypeHierarchyResolver; @@ -72,7 +71,6 @@ public class InjectorForTopDownAnalyzerForJs { private OverloadingConflictResolver overloadingConflictResolver; private ImportsResolver importsResolver; private ScriptHeaderResolver scriptHeaderResolver; - private DelegationResolver delegationResolver; private OverloadResolver overloadResolver; private OverrideResolver overrideResolver; private TypeHierarchyResolver typeHierarchyResolver; @@ -107,7 +105,6 @@ public class InjectorForTopDownAnalyzerForJs { this.overloadingConflictResolver = new OverloadingConflictResolver(); this.importsResolver = new ImportsResolver(); this.scriptHeaderResolver = new ScriptHeaderResolver(); - this.delegationResolver = new DelegationResolver(); this.overloadResolver = new OverloadResolver(); this.overrideResolver = new OverrideResolver(); this.typeHierarchyResolver = new TypeHierarchyResolver(); @@ -116,7 +113,6 @@ public class InjectorForTopDownAnalyzerForJs { this.topDownAnalyzer.setBodyResolver(bodyResolver); this.topDownAnalyzer.setContext(topDownAnalysisContext); this.topDownAnalyzer.setDeclarationResolver(declarationResolver); - this.topDownAnalyzer.setDelegationResolver(delegationResolver); this.topDownAnalyzer.setModuleDescriptor(moduleDescriptor); this.topDownAnalyzer.setNamespaceFactory(namespaceFactory); this.topDownAnalyzer.setOverloadResolver(overloadResolver); @@ -185,9 +181,6 @@ public class InjectorForTopDownAnalyzerForJs { scriptHeaderResolver.setTopDownAnalysisParameters(topDownAnalysisParameters); scriptHeaderResolver.setTrace(bindingTrace); - delegationResolver.setContext(topDownAnalysisContext); - delegationResolver.setTrace(bindingTrace); - overloadResolver.setContext(topDownAnalysisContext); overloadResolver.setTrace(bindingTrace); From 31db3456ca06da8ac2c5a745d367aced8305bf01 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Wed, 15 Aug 2012 15:56:34 +0300 Subject: [PATCH 30/36] enum entries which overrides methods --- .../jetbrains/jet/codegen/ClassCodegen.java | 27 +- .../jet/codegen/ClosureAnnotator.java | 18 + .../jet/codegen/ConstructorFrameMap.java | 10 +- .../jet/codegen/ExpressionCodegen.java | 468 +++++++++++------- .../codegen/ImplementationBodyCodegen.java | 328 +++++++----- .../jetbrains/jet/codegen/JetTypeMapper.java | 131 +++-- .../testData/codegen/enum/abstractmethod.kt | 10 + .../jetbrains/jet/codegen/EnumGenTest.java | 31 ++ 8 files changed, 658 insertions(+), 365 deletions(-) create mode 100644 compiler/testData/codegen/enum/abstractmethod.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java index e1f3aec4775..acd8e708d86 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.codegen; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassKind; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -56,32 +57,44 @@ public class ClassCodegen { // different for the case when we compute closures generateImplementation(context, aClass, OwnerKind.IMPLEMENTATION, contextForInners.accessors, classBuilder); } - + for (JetDeclaration declaration : aClass.getDeclarations()) { - if (declaration instanceof JetClass && !(declaration instanceof JetEnumEntry)) { + if (declaration instanceof JetClass) { + if (declaration instanceof JetEnumEntry && !state.getInjector().getClosureAnnotator().enumEntryNeedSubclass( + (JetEnumEntry) declaration)) { + continue; + } + generate(contextForInners, (JetClass) declaration); } if (declaration instanceof JetClassObject) { - generate(contextForInners, ((JetClassObject)declaration).getObjectDeclaration()); + generate(contextForInners, ((JetClassObject) declaration).getObjectDeclaration()); } } if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES) { generateImplementation(context, aClass, OwnerKind.IMPLEMENTATION, contextForInners.accessors, classBuilder); } - + classBuilder.done(); } - private void generateImplementation(CodegenContext context, JetClassOrObject aClass, OwnerKind kind, HashMap accessors, ClassBuilder classBuilder) { + private void generateImplementation( + CodegenContext context, + JetClassOrObject aClass, + OwnerKind kind, + HashMap accessors, + ClassBuilder classBuilder + ) { ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass); CodegenContext classContext = context.intoClass(descriptor, kind, jetTypeMapper); classContext.copyAccessors(accessors); new ImplementationBodyCodegen(aClass, classContext, classBuilder, state).generate(); - if (aClass instanceof JetClass && ((JetClass)aClass).isTrait()) { + if (aClass instanceof JetClass && ((JetClass) aClass).isTrait()) { ClassBuilder traitBuilder = state.forTraitImplementation(descriptor); - new TraitImplBodyCodegen(aClass, context.intoClass(descriptor, OwnerKind.TRAIT_IMPL, jetTypeMapper), traitBuilder, state).generate(); + new TraitImplBodyCodegen(aClass, context.intoClass(descriptor, OwnerKind.TRAIT_IMPL, jetTypeMapper), traitBuilder, state) + .generate(); traitBuilder.done(); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java index 9e1d91500ec..14a7e835b6c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java @@ -51,6 +51,7 @@ public class ClosureAnnotator { private BindingContext bindingContext; private List files; + private final Map enumEntryNeedSubclass = new HashMap(); @Inject public void setBindingContext(BindingContext bindingContext) { @@ -229,6 +230,16 @@ public class ClosureAnnotator { return other != null; } + public boolean enumEntryNeedSubclass(JetEnumEntry enumEntry) { + ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, enumEntry); + return enumEntryNeedSubclass.get(descriptor); + } + + public boolean enumEntryNeedSubclass(ClassDescriptor enumEntry) { + Boolean aBoolean = enumEntryNeedSubclass.get(enumEntry); + return aBoolean != null && aBoolean; + } + private class MyJetVisitorVoid extends JetVisitorVoid { private final LinkedList classStack = new LinkedList(); private final LinkedList nameStack = new LinkedList(); @@ -285,6 +296,13 @@ public class ClosureAnnotator { nameStack.pop(); } + @Override + public void visitEnumEntry(JetEnumEntry enumEntry) { + ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, enumEntry); + enumEntryNeedSubclass.put(descriptor, !enumEntry.getDeclarations().isEmpty()); + super.visitEnumEntry(enumEntry); + } + @Override public void visitClassObject(JetClassObject classObject) { JvmClassName name = recordClassObject(classObject); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java b/compiler/backend/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java index cb3ffe37da7..1bb7d916fde 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java @@ -31,7 +31,7 @@ import java.util.List; */ public class ConstructorFrameMap extends FrameMap { private int myOuterThisIndex = -1; - private int myTypeInfoIndex = -1; + private int myTypeInfoIndex = -1; public ConstructorFrameMap(CallableMethod callableMethod, @Nullable ConstructorDescriptor descriptor, boolean hasThis0) { enterTemp(); // this @@ -43,14 +43,16 @@ public class ConstructorFrameMap extends FrameMap { List explicitArgTypes = callableMethod.getValueParameterTypes(); - if(descriptor != null && descriptor.getContainingDeclaration().getKind() == ClassKind.ENUM_CLASS) { + if (descriptor != null && + (descriptor.getContainingDeclaration().getKind() == ClassKind.ENUM_CLASS || + descriptor.getContainingDeclaration().getKind() == ClassKind.ENUM_ENTRY)) { enterTemp(); // name enterTemp(); // ordinal } List paramDescrs = descriptor != null - ? descriptor.getValueParameters() - : Collections.emptyList(); + ? descriptor.getValueParameters() + : Collections.emptyList(); for (int i = 0; i < paramDescrs.size(); i++) { ValueParameterDescriptor parameter = paramDescrs.get(i); enter(parameter, explicitArgTypes.get(i).getSize()); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 9191951e0c9..c86f9ceb7e4 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -79,7 +79,7 @@ public class ExpressionCodegen extends JetVisitor { static class BlockStackElement { } - + static class LoopBlockStackElement extends BlockStackElement { final Label continueLabel; final Label breakLabel; @@ -101,11 +101,13 @@ public class ExpressionCodegen extends JetVisitor { } - public ExpressionCodegen(MethodVisitor v, - FrameMap myMap, - Type returnType, - CodegenContext context, - GenerationState state) { + public ExpressionCodegen( + MethodVisitor v, + FrameMap myMap, + Type returnType, + CodegenContext context, + GenerationState state + ) { this.myFrameMap = myMap; this.typeMapper = state.getInjector().getJetTypeMapper(); this.returnType = returnType; @@ -123,11 +125,13 @@ public class ExpressionCodegen extends JetVisitor { } StackValue castToRequiredTypeOfInterfaceIfNeeded(StackValue inner, DeclarationDescriptor provided, @Nullable ClassDescriptor required) { - if (required == null) + if (required == null) { return inner; + } - if (provided instanceof CallableDescriptor) - provided = ((CallableDescriptor)provided).getReceiverParameter().getType().getConstructor().getDeclarationDescriptor(); + if (provided instanceof CallableDescriptor) { + provided = ((CallableDescriptor) provided).getReceiverParameter().getType().getConstructor().getDeclarationDescriptor(); + } assert provided instanceof ClassDescriptor; @@ -229,8 +233,9 @@ public class ExpressionCodegen extends JetVisitor { } private static boolean isEmptyExpression(JetElement expr) { - if (expr == null) + if (expr == null) { return true; + } if (expr instanceof JetBlockExpression) { JetBlockExpression blockExpression = (JetBlockExpression) expr; List statements = blockExpression.getStatements(); @@ -310,14 +315,14 @@ public class ExpressionCodegen extends JetVisitor { return StackValue.onStack(Type.VOID_TYPE); } - + @Override public StackValue visitDoWhileExpression(JetDoWhileExpression expression, StackValue receiver) { Label condition = new Label(); v.mark(condition); Label end = new Label(); - + blockStackElements.push(new LoopBlockStackElement(end, condition, targetLabel(expression))); gen(expression.getBody(), Type.VOID_TYPE); @@ -361,12 +366,15 @@ public class ExpressionCodegen extends JetVisitor { FunctionDescriptor nextDescriptor = bindingContext.get(BindingContext.LOOP_RANGE_NEXT, loopRange); DeclarationDescriptor hasNextDescriptor = bindingContext.get(BindingContext.LOOP_RANGE_HAS_NEXT, loopRange); - if (iteratorDescriptor == null) + if (iteratorDescriptor == null) { throw new IllegalStateException("No iterator() method " + DiagnosticUtils.atLocation(loopRange)); - if (nextDescriptor == null) + } + if (nextDescriptor == null) { throw new IllegalStateException("No next() method " + DiagnosticUtils.atLocation(loopRange)); - if (hasNextDescriptor == null) + } + if (hasNextDescriptor == null) { throw new IllegalStateException("No hasNext method or property" + DiagnosticUtils.atLocation(loopRange)); + } final JetParameter loopParameter = expression.getLoopParameter(); final VariableDescriptor parameterDescriptor = bindingContext.get(BindingContext.VALUE_PARAMETER, loopParameter); @@ -381,7 +389,7 @@ public class ExpressionCodegen extends JetVisitor { gen(expression.getLoopRange(), boxType(loopRangeType)); invokeFunctionNoParams(iteratorDescriptor, asmIterType, v); v.store(iteratorVar, asmIterType); - + Label end = new Label(); if (iteratorType.isNullable()) { v.load(iteratorVar, TYPE_OBJECT); @@ -398,11 +406,11 @@ public class ExpressionCodegen extends JetVisitor { invokeFunctionNoParams(hND, Type.BOOLEAN_TYPE, v); } else { -// hND = ((PropertyDescriptor) hasNextDescriptor).getGetter(); -// if (hND != null) -// invokeFunctionNoParams(hND, Type.BOOLEAN_TYPE, v); -// else - intermediateValueForProperty((PropertyDescriptor) hasNextDescriptor, false, null).put(Type.BOOLEAN_TYPE, v); + // hND = ((PropertyDescriptor) hasNextDescriptor).getGetter(); + // if (hND != null) + // invokeFunctionNoParams(hND, Type.BOOLEAN_TYPE, v); + // else + intermediateValueForProperty((PropertyDescriptor) hasNextDescriptor, false, null).put(Type.BOOLEAN_TYPE, v); } v.ifeq(end); @@ -504,7 +512,7 @@ public class ExpressionCodegen extends JetVisitor { StackValue value = gen(expression.getLoopRange()); if (value instanceof StackValue.Local) { - myArrayVar = ((StackValue.Local)value).index; + myArrayVar = ((StackValue.Local) value).index; localArrayVar = true; } else { @@ -580,7 +588,7 @@ public class ExpressionCodegen extends JetVisitor { v.iconst(1); v.add(Type.INT_TYPE); v.store(myCountVar, Type.INT_TYPE); - + v.load(myCountVar, Type.INT_TYPE); v.iflt(end); @@ -636,8 +644,8 @@ public class ExpressionCodegen extends JetVisitor { @Override public StackValue visitBreakExpression(JetBreakExpression expression, StackValue receiver) { JetSimpleNameExpression labelElement = expression.getTargetLabel(); - - for(int i = blockStackElements.size()-1; i >= 0; --i) { + + for (int i = blockStackElements.size() - 1; i >= 0; --i) { BlockStackElement stackElement = blockStackElements.get(i); if (stackElement instanceof FinallyBlockStackElement) { FinallyBlockStackElement finallyBlockStackElement = (FinallyBlockStackElement) stackElement; @@ -647,7 +655,9 @@ public class ExpressionCodegen extends JetVisitor { } else if (stackElement instanceof LoopBlockStackElement) { LoopBlockStackElement loopBlockStackElement = (LoopBlockStackElement) stackElement; - if (labelElement == null || loopBlockStackElement.targetLabel != null && labelElement.getReferencedName().equals(loopBlockStackElement.targetLabel.getReferencedName())) { + if (labelElement == null || + loopBlockStackElement.targetLabel != null && + labelElement.getReferencedName().equals(loopBlockStackElement.targetLabel.getReferencedName())) { v.goTo(loopBlockStackElement.breakLabel); return StackValue.none(); } @@ -656,7 +666,7 @@ public class ExpressionCodegen extends JetVisitor { throw new UnsupportedOperationException(); } } - + throw new UnsupportedOperationException(); } @@ -664,7 +674,7 @@ public class ExpressionCodegen extends JetVisitor { public StackValue visitContinueExpression(JetContinueExpression expression, StackValue receiver) { JetSimpleNameExpression labelElement = expression.getTargetLabel(); - for(int i = blockStackElements.size()-1; i >= 0; --i) { + for (int i = blockStackElements.size() - 1; i >= 0; --i) { BlockStackElement stackElement = blockStackElements.get(i); if (stackElement instanceof FinallyBlockStackElement) { FinallyBlockStackElement finallyBlockStackElement = (FinallyBlockStackElement) stackElement; @@ -673,7 +683,9 @@ public class ExpressionCodegen extends JetVisitor { } else if (stackElement instanceof LoopBlockStackElement) { LoopBlockStackElement loopBlockStackElement = (LoopBlockStackElement) stackElement; - if (labelElement == null || loopBlockStackElement.targetLabel != null && labelElement.getReferencedName().equals(loopBlockStackElement.targetLabel.getReferencedName())) { + if (labelElement == null || + loopBlockStackElement.targetLabel != null && + labelElement.getReferencedName().equals(loopBlockStackElement.targetLabel.getReferencedName())) { v.goTo(loopBlockStackElement.continueLabel); return StackValue.none(); } @@ -743,8 +755,8 @@ public class ExpressionCodegen extends JetVisitor { } else { String text = entry instanceof JetEscapeStringTemplateEntry - ? ((JetEscapeStringTemplateEntry) entry).getUnescapedValue() - : entry.getText(); + ? ((JetEscapeStringTemplateEntry) entry).getUnescapedValue() + : entry.getText(); v.aconst(text); invokeAppendMethod(JL_STRING_TYPE); } @@ -809,12 +821,13 @@ public class ExpressionCodegen extends JetVisitor { if (closure.isCaptureReceiver() != null) { k++; - v.load(context.getContextDescriptor().getContainingDeclaration() instanceof NamespaceDescriptor ? 0: 1, closure.isCaptureReceiver()); + v.load(context.getContextDescriptor().getContainingDeclaration() instanceof NamespaceDescriptor ? 0 : 1, + closure.isCaptureReceiver()); } for (int i = 0; i < closure.getArgs().size(); i++) { StackValue arg = closure.getArgs().get(i); - arg.put(cons.getArgumentTypes()[i+k], v); + arg.put(cons.getArgumentTypes()[i + k], v); } v.invokespecial(closure.getClassname().getInternalName(), "", cons.getDescriptor()); @@ -839,26 +852,32 @@ public class ExpressionCodegen extends JetVisitor { v.load(context.isStatic() ? 0 : 1, closureCodegen.captureReceiver); consArgTypes.add(closureCodegen.captureReceiver); } - + for (Map.Entry entry : closureCodegen.closure.entrySet()) { if (entry.getKey() instanceof VariableDescriptor && !(entry.getKey() instanceof PropertyDescriptor)) { Type sharedVarType = typeMapper.getSharedVarType(entry.getKey()); - if (sharedVarType == null) - sharedVarType = state.getInjector().getJetTypeMapper().mapType(((VariableDescriptor) entry.getKey()).getType(), MapTypeMode.VALUE); + if (sharedVarType == null) { + sharedVarType = state.getInjector().getJetTypeMapper() + .mapType(((VariableDescriptor) entry.getKey()).getType(), MapTypeMode.VALUE); + } consArgTypes.add(sharedVarType); entry.getValue().getOuterValue().put(sharedVarType, v); } } if (closureCodegen.superCall != null) { - ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, closureCodegen.superCall.getCalleeExpression().getConstructorReferenceExpression()); - CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, typeMapper.hasThis0(superConstructor.getContainingDeclaration())); + ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, + closureCodegen.superCall + .getCalleeExpression() + .getConstructorReferenceExpression()); + CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, + typeMapper.hasThis0(superConstructor.getContainingDeclaration())); Type[] argumentTypes = superCallable.getSignature().getAsmMethod().getArgumentTypes(); Collections.addAll(consArgTypes, argumentTypes); ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, closureCodegen.superCall.getCalleeExpression()); pushMethodArguments(resolvedCall, Arrays.asList(argumentTypes)); } - + Method cons = new Method("", Type.VOID_TYPE, consArgTypes.toArray(new Type[consArgTypes.size()])); v.invokespecial(closure.getClassname().getInternalName(), "", cons.getDescriptor()); return StackValue.onStack(closure.getClassname().getAsmType()); @@ -885,7 +904,7 @@ public class ExpressionCodegen extends JetVisitor { final Type type = sharedVarType != null ? sharedVarType : asmType(variableDescriptor.getType()); myFrameMap.enter(variableDescriptor, type.getSize()); } - + if (statement instanceof JetNamedFunction) { DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, statement); myFrameMap.enter(descriptor, 1); @@ -895,7 +914,9 @@ public class ExpressionCodegen extends JetVisitor { StackValue answer = StackValue.none(); for (int i = 0, statementsSize = statements.size(); i < statementsSize; i++) { JetElement statement = statements.get(i); - if (i == statements.size() - 1 /*&& statement instanceof JetExpression && !bindingContext.get(BindingContext.STATEMENT, statement)*/) { + if (i == + statements.size() - + 1 /*&& statement instanceof JetExpression && !bindingContext.get(BindingContext.STATEMENT, statement)*/) { answer = gen(statement); } else { @@ -962,7 +983,7 @@ public class ExpressionCodegen extends JetVisitor { } private void doFinallyOnReturn() { - for(int i = blockStackElements.size()-1; i >= 0; --i) { + for (int i = blockStackElements.size() - 1; i >= 0; --i) { BlockStackElement stackElement = blockStackElements.get(i); if (stackElement instanceof FinallyBlockStackElement) { FinallyBlockStackElement finallyBlockStackElement = (FinallyBlockStackElement) stackElement; @@ -976,7 +997,7 @@ public class ExpressionCodegen extends JetVisitor { } } } - + @Override public StackValue visitReturnExpression(JetReturnExpression expression, StackValue receiver) { final JetExpression returnedExpression = expression.getReturnedExpression(); @@ -993,7 +1014,7 @@ public class ExpressionCodegen extends JetVisitor { public void returnExpression(JetExpression expr) { StackValue lastValue = gen(expr); - + if (lastValue.type != Type.VOID_TYPE) { lastValue.put(returnType, v); v.areturn(returnType); @@ -1006,12 +1027,12 @@ public class ExpressionCodegen extends JetVisitor { private static boolean endsWithReturn(JetElement bodyExpression) { if (bodyExpression instanceof JetBlockExpression) { final List statements = ((JetBlockExpression) bodyExpression).getStatements(); - return statements.size() > 0 && statements.get(statements.size()-1) instanceof JetReturnExpression; + return statements.size() > 0 && statements.get(statements.size() - 1) instanceof JetReturnExpression; } - + return bodyExpression instanceof JetReturnExpression; } - + @Override public StackValue visitSimpleNameExpression(JetSimpleNameExpression expression, StackValue receiver) { ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression); @@ -1036,7 +1057,7 @@ public class ExpressionCodegen extends JetVisitor { IntrinsicMethod intrinsic = null; if (descriptor instanceof CallableMemberDescriptor) { CallableMemberDescriptor memberDescriptor = (CallableMemberDescriptor) descriptor; - while(memberDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { + while (memberDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { memberDescriptor = memberDescriptor.getOverriddenDescriptors().iterator().next(); } intrinsic = state.getInjector().getIntrinsics().getIntrinsic(memberDescriptor); @@ -1056,17 +1077,18 @@ public class ExpressionCodegen extends JetVisitor { if (descriptor instanceof PropertyDescriptor) { PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; - + if (propertyDescriptor.isObjectDeclaration()) { - ClassDescriptor classDescriptor = (ClassDescriptor) propertyDescriptor.getReturnType().getConstructor().getDeclarationDescriptor(); + ClassDescriptor classDescriptor = + (ClassDescriptor) propertyDescriptor.getReturnType().getConstructor().getDeclarationDescriptor(); + assert classDescriptor != null; if (classDescriptor.getKind() == ClassKind.ENUM_ENTRY) { ClassDescriptor containing = (ClassDescriptor) classDescriptor.getContainingDeclaration().getContainingDeclaration(); + assert containing != null; Type type = typeMapper.mapType(containing.getDefaultType(), MapTypeMode.VALUE); - StackValue.field(type, JvmClassName.byType(type), classDescriptor.getName().getName(), true).put(TYPE_OBJECT, v); - - // todo: for now we don't generate classes for enum entries, so we need this hack - type = typeMapper.mapType(classDescriptor.getDefaultType(), MapTypeMode.VALUE); - return StackValue.onStack(type); + Type entryType = typeMapper.mapType(classDescriptor.getDefaultType(), MapTypeMode.VALUE); + StackValue.field(type, JvmClassName.byType(type), classDescriptor.getName().getName(), true).put(entryType, v); + return StackValue.onStack(entryType); } else { Type type = typeMapper.mapType(classDescriptor.getDefaultType(), MapTypeMode.VALUE); @@ -1075,11 +1097,13 @@ public class ExpressionCodegen extends JetVisitor { } boolean isStatic = container instanceof NamespaceDescriptor; - final boolean directToField = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL ; + final boolean directToField = + expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL; JetExpression r = getReceiverForSelector(expression); final boolean isSuper = r instanceof JetSuperExpression; propertyDescriptor = accessablePropertyDescriptor(propertyDescriptor); - final StackValue.Property iValue = intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression)r : null); + final StackValue.Property iValue = + intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression) r : null); if (!directToField && resolvedCall != null && !isSuper) { receiver.put(propertyDescriptor.getReceiverParameter().exists() || isStatic ? receiver.type @@ -1088,20 +1112,24 @@ public class ExpressionCodegen extends JetVisitor { else { if (!isStatic) { if (receiver == StackValue.none()) { - if (resolvedCall == null) + if (resolvedCall == null) { receiver = generateThisOrOuter((ClassDescriptor) propertyDescriptor.getContainingDeclaration()); + } else { - if (resolvedCall.getThisObject() instanceof ExtensionReceiver) - receiver = generateReceiver(((ExtensionReceiver)resolvedCall.getThisObject()).getDeclarationDescriptor()); - else + if (resolvedCall.getThisObject() instanceof ExtensionReceiver) { + receiver = generateReceiver(((ExtensionReceiver) resolvedCall.getThisObject()).getDeclarationDescriptor()); + } + else { receiver = generateThisOrOuter((ClassDescriptor) propertyDescriptor.getContainingDeclaration()); + } } } JetType receiverType = bindingContext.get(BindingContext.EXPRESSION_TYPE, r); - receiver.put(receiverType != null && !isSuper? asmType(receiverType) : TYPE_OBJECT, v); + receiver.put(receiverType != null && !isSuper ? asmType(receiverType) : TYPE_OBJECT, v); if (receiverType != null) { ClassDescriptor propReceiverDescriptor = (ClassDescriptor) propertyDescriptor.getContainingDeclaration(); - if (!CodegenUtil.isInterface(propReceiverDescriptor) && CodegenUtil.isInterface(receiverType.getConstructor().getDeclarationDescriptor())) { + if (!CodegenUtil.isInterface(propReceiverDescriptor) && + CodegenUtil.isInterface(receiverType.getConstructor().getDeclarationDescriptor())) { // I hope it happens only in case of required super class for traits assert propReceiverDescriptor != null; v.checkcast(asmType(propReceiverDescriptor.getDefaultType())); @@ -1115,13 +1143,14 @@ public class ExpressionCodegen extends JetVisitor { if (descriptor instanceof ClassDescriptor) { PsiElement declaration = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor); if (declaration instanceof JetClass) { - final ClassDescriptor descriptor1 = ((ClassDescriptor)descriptor).getClassObjectDescriptor(); + final ClassDescriptor descriptor1 = ((ClassDescriptor) descriptor).getClassObjectDescriptor(); assert descriptor1 != null; final Type type = typeMapper.mapType(descriptor1.getDefaultType(), MapTypeMode.VALUE); return StackValue.field(type, - JvmClassName.byType(typeMapper.mapType(((ClassDescriptor) descriptor).getDefaultType(), MapTypeMode.IMPL)), - "$classobj", - true); + JvmClassName.byType(typeMapper.mapType(((ClassDescriptor) descriptor).getDefaultType(), + MapTypeMode.IMPL)), + "$classobj", + true); } else { // todo ? @@ -1149,7 +1178,8 @@ public class ExpressionCodegen extends JetVisitor { if (value instanceof StackValue.FieldForSharedVar) { StackValue.FieldForSharedVar fieldForSharedVar = (StackValue.FieldForSharedVar) value; Type sharedType = StackValue.sharedTypeForType(value.type); - v.visitFieldInsn(Opcodes.GETFIELD, fieldForSharedVar.owner.getInternalName(), fieldForSharedVar.name, sharedType.getDescriptor()); + v.visitFieldInsn(Opcodes.GETFIELD, fieldForSharedVar.owner.getInternalName(), fieldForSharedVar.name, + sharedType.getDescriptor()); } return value; @@ -1215,11 +1245,15 @@ public class ExpressionCodegen extends JetVisitor { int opcode = isStatic ? Opcodes.INVOKESTATIC : isInterface ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL; v.visitMethodInsn(opcode, owner.getInternalName(), functionDescriptor.getName().getName(), - typeMapper.mapSignature(functionDescriptor.getName(),functionDescriptor).getAsmMethod().getDescriptor()); + typeMapper.mapSignature(functionDescriptor.getName(), functionDescriptor).getAsmMethod().getDescriptor()); StackValue.onStack(asmType(functionDescriptor.getReturnType())).coerce(type, v); } - public StackValue.Property intermediateValueForProperty(PropertyDescriptor propertyDescriptor, final boolean forceField, @Nullable JetSuperExpression superExpression) { + public StackValue.Property intermediateValueForProperty( + PropertyDescriptor propertyDescriptor, + final boolean forceField, + @Nullable JetSuperExpression superExpression + ) { boolean isSuper = superExpression != null; DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration(); @@ -1232,23 +1266,27 @@ public class ExpressionCodegen extends JetVisitor { PropertyDescriptor initialDescriptor = propertyDescriptor; propertyDescriptor = initialDescriptor.getOriginal(); boolean isInsideClass = !isFakeOverride && (((containingDeclaration == context.getThisDescriptor()) || - (context.getParentContext() instanceof CodegenContexts.NamespaceContext) && context.getParentContext().getContextDescriptor() == containingDeclaration) - && contextKind() != OwnerKind.TRAIT_IMPL); + (context.getParentContext() instanceof CodegenContexts.NamespaceContext) && + context.getParentContext().getContextDescriptor() == containingDeclaration) + && contextKind() != OwnerKind.TRAIT_IMPL); Method getter = null; Method setter = null; if (!forceField) { //noinspection ConstantConditions - if (isInsideClass && (propertyDescriptor.getGetter() == null || propertyDescriptor.getGetter().isDefault() && propertyDescriptor.getGetter().getModality() == Modality.FINAL)) { + if (isInsideClass && + (propertyDescriptor.getGetter() == null || + propertyDescriptor.getGetter().isDefault() && propertyDescriptor.getGetter().getModality() == Modality.FINAL)) { getter = null; } else { if (isSuper) { PsiElement enclosingElement = bindingContext.get(BindingContext.LABEL_TARGET, superExpression.getTargetLabel()); - ClassDescriptor enclosed = (ClassDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, enclosingElement); + ClassDescriptor enclosed = + (ClassDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, enclosingElement); if (!CodegenUtil.isInterface(containingDeclaration)) { if (enclosed != null && enclosed != context.getThisDescriptor()) { CodegenContext c = context; - while(c.getContextDescriptor() != enclosed) { + while (c.getContextDescriptor() != enclosed) { c = c.getParentContext(); } propertyDescriptor = (PropertyDescriptor) c.getAccessor(propertyDescriptor); @@ -1269,20 +1307,22 @@ public class ExpressionCodegen extends JetVisitor { if (getter == null && propertyDescriptor.getReceiverParameter().exists()) { throw new IllegalStateException(); } - } //noinspection ConstantConditions - if (isInsideClass && (propertyDescriptor.getSetter() == null || propertyDescriptor.getSetter().isDefault() && propertyDescriptor.getSetter().getModality() == Modality.FINAL)) { + if (isInsideClass && + (propertyDescriptor.getSetter() == null || + propertyDescriptor.getSetter().isDefault() && propertyDescriptor.getSetter().getModality() == Modality.FINAL)) { setter = null; } else { - JvmPropertyAccessorSignature jvmMethodSignature = typeMapper.mapSetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION); + JvmPropertyAccessorSignature jvmMethodSignature = + typeMapper.mapSetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION); setter = jvmMethodSignature != null ? jvmMethodSignature.getJvmMethodSignature().getAsmMethod() : null; if (propertyDescriptor.getSetter() == null) { setter = null; } - + if (setter == null && propertyDescriptor.isVar() && propertyDescriptor.getReceiverParameter().exists()) { throw new IllegalStateException(); } @@ -1306,26 +1346,33 @@ public class ExpressionCodegen extends JetVisitor { // TODO ugly CallableMethod callableMethod = typeMapper.mapToCallableMethod(propertyDescriptor.getGetter(), isSuper, contextKind()); invokeOpcode = callableMethod.getInvokeOpcode(); - owner = isFakeOverride && !overridesTrait && !CodegenUtil.isInterface(initialDescriptor.getContainingDeclaration()) ? JvmClassName.byType(typeMapper.mapType(((ClassDescriptor)initialDescriptor.getContainingDeclaration()).getDefaultType(), MapTypeMode.IMPL)): callableMethod.getOwner(); + owner = isFakeOverride && !overridesTrait && !CodegenUtil.isInterface(initialDescriptor.getContainingDeclaration()) + ? JvmClassName.byType(typeMapper.mapType( + ((ClassDescriptor) initialDescriptor.getContainingDeclaration()).getDefaultType(), MapTypeMode.IMPL)) + : callableMethod.getOwner(); ownerParam = callableMethod.getDefaultImplParam(); } - return StackValue.property(propertyDescriptor.getName().getName(), owner, ownerParam, asmType(propertyDescriptor.getType()), isStatic, isInterface, isSuper, getter, setter, invokeOpcode); + return StackValue + .property(propertyDescriptor.getName().getName(), owner, ownerParam, asmType(propertyDescriptor.getType()), isStatic, + isInterface, isSuper, getter, setter, invokeOpcode); } private PropertyDescriptor accessablePropertyDescriptor(PropertyDescriptor propertyDescriptor) { - if ((propertyDescriptor.getVisibility() == Visibilities.PRIVATE ||(propertyDescriptor.getSetter() != null && propertyDescriptor.getSetter().getVisibility() == Visibilities.PRIVATE)) - && !DescriptorUtils.isClassObject(propertyDescriptor.getContainingDeclaration()) - && propertyDescriptor.getContainingDeclaration() instanceof ClassDescriptor) { + if ((propertyDescriptor.getVisibility() == Visibilities.PRIVATE || + (propertyDescriptor.getSetter() != null && propertyDescriptor.getSetter().getVisibility() == Visibilities.PRIVATE)) + && !DescriptorUtils.isClassObject(propertyDescriptor.getContainingDeclaration()) + && propertyDescriptor.getContainingDeclaration() instanceof ClassDescriptor) { if (context.getClassOrNamespaceDescriptor() != propertyDescriptor.getContainingDeclaration()) { DeclarationDescriptor enclosed = propertyDescriptor.getContainingDeclaration(); if (enclosed != context.getThisDescriptor()) { CodegenContext c = context; - while(c != null && c.getContextDescriptor() != enclosed) { + while (c != null && c.getContextDescriptor() != enclosed) { c = c.getParentContext(); } - if(c != null) + if (c != null) { propertyDescriptor = (PropertyDescriptor) c.getAccessor(propertyDescriptor); + } } } } @@ -1376,10 +1423,12 @@ public class ExpressionCodegen extends JetVisitor { } } - private StackValue invokeFunction(JetCallExpression expression, + private StackValue invokeFunction( + JetCallExpression expression, FunctionDescriptor fd, StackValue receiver, - ResolvedCall resolvedCall) { + ResolvedCall resolvedCall + ) { boolean superCall = false; if (expression.getParent() instanceof JetQualifiedExpression) { final JetExpression receiverExpression = ((JetQualifiedExpression) expression.getParent()).getReceiverExpression(); @@ -1390,12 +1439,13 @@ public class ExpressionCodegen extends JetVisitor { PsiElement enclosingElement = bindingContext.get(BindingContext.LABEL_TARGET, superExpression.getTargetLabel()); ClassDescriptor enclosed = (ClassDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, enclosingElement); if (!CodegenUtil.isInterface(fd.getContainingDeclaration())) { - if(enclosed == null) { + if (enclosed == null) { enclosed = (ClassDescriptor) fd.getContainingDeclaration(); } if (enclosed != context.getThisDescriptor()) { CodegenContext c = context; - while(!(c instanceof CodegenContexts.ClassContext) || !DescriptorUtils.isSubclass(c.getThisDescriptor(), enclosed)) { + while (!(c instanceof CodegenContexts.ClassContext) || + !DescriptorUtils.isSubclass(c.getThisDescriptor(), enclosed)) { c = c.getParentContext(); } fd = (FunctionDescriptor) c.getAccessor(fd); @@ -1407,13 +1457,13 @@ public class ExpressionCodegen extends JetVisitor { } if (fd.getVisibility() == Visibilities.PRIVATE - && !DescriptorUtils.isClassObject(fd.getContainingDeclaration()) - && fd.getContainingDeclaration() instanceof ClassDescriptor) { + && !DescriptorUtils.isClassObject(fd.getContainingDeclaration()) + && fd.getContainingDeclaration() instanceof ClassDescriptor) { if (context.getClassOrNamespaceDescriptor() != fd.getContainingDeclaration()) { DeclarationDescriptor enclosed = fd.getContainingDeclaration(); if (enclosed != context.getThisDescriptor()) { CodegenContext c = context; - while(c.getContextDescriptor() != enclosed) { + while (c.getContextDescriptor() != enclosed) { c = c.getParentContext(); } fd = (FunctionDescriptor) c.getAccessor(fd); @@ -1437,10 +1487,10 @@ public class ExpressionCodegen extends JetVisitor { for (ValueArgument argument : expression.getValueArguments()) { args.add(argument.getArgumentExpression()); } - Type callType = typeMapper.mapType(resolvedCall.getCandidateDescriptor().getReturnType(),MapTypeMode.VALUE); + Type callType = typeMapper.mapType(resolvedCall.getCandidateDescriptor().getReturnType(), MapTypeMode.VALUE); Type exprType = expressionType(expression); StackValue stackValue = intrinsic.generate(this, v, callType, expression, args, receiver, state); - stackValue.put(exprType,v); + stackValue.put(exprType, v); return StackValue.onStack(exprType); } } @@ -1483,7 +1533,9 @@ public class ExpressionCodegen extends JetVisitor { else if (fd instanceof ExpressionAsFunctionDescriptor) { return true; } - else if (fd instanceof SimpleFunctionDescriptor && (fd.getContainingDeclaration() instanceof FunctionDescriptor || fd.getContainingDeclaration() instanceof ScriptDescriptor)) { + else if (fd instanceof SimpleFunctionDescriptor && + (fd.getContainingDeclaration() instanceof FunctionDescriptor || + fd.getContainingDeclaration() instanceof ScriptDescriptor)) { return true; } else { @@ -1498,11 +1550,12 @@ public class ExpressionCodegen extends JetVisitor { gen(expression.getCalleeExpression(), calleeType); } - ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression()); + ResolvedCall resolvedCall = + bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression()); assert resolvedCall != null; if (resolvedCall instanceof VariableAsFunctionResolvedCall) { - resolvedCall = ((VariableAsFunctionResolvedCall)resolvedCall).getFunctionCall(); + resolvedCall = ((VariableAsFunctionResolvedCall) resolvedCall).getFunctionCall(); } if (!(resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor)) { // otherwise already @@ -1514,13 +1567,19 @@ public class ExpressionCodegen extends JetVisitor { } int mask = pushMethodArguments(expression, callableMethod.getValueParameterTypes()); - if (mask == 0) + if (mask == 0) { callableMethod.invoke(v); - else + } + else { callableMethod.invokeWithDefault(v, mask); + } } - private void genThisAndReceiverFromResolvedCall(StackValue receiver, ResolvedCall resolvedCall, CallableMethod callableMethod) { + private void genThisAndReceiverFromResolvedCall( + StackValue receiver, + ResolvedCall resolvedCall, + CallableMethod callableMethod + ) { receiver = StackValue.receiver(resolvedCall, receiver, this, callableMethod, state); receiver.put(receiver.type, v); } @@ -1533,9 +1592,12 @@ public class ExpressionCodegen extends JetVisitor { if (DescriptorUtils.isClassObject(classReceiverDeclarationDescriptor)) { ClassDescriptor containingDeclaration = (ClassDescriptor) classReceiverDeclarationDescriptor.getContainingDeclaration(); Type classObjType = typeMapper.mapType(containingDeclaration.getDefaultType(), MapTypeMode.IMPL); - if (context.getContextDescriptor() instanceof ConstructorDescriptor && classReceiverDeclarationDescriptor.getDefaultType().equals(((ConstructorDescriptor)context.getContextDescriptor()).getReturnType())) { + if (context.getContextDescriptor() instanceof ConstructorDescriptor && + classReceiverDeclarationDescriptor.getDefaultType() + .equals(((ConstructorDescriptor) context.getContextDescriptor()).getReturnType())) { v.load(0, classObjType); - } else { + } + else { v.getstatic(classObjType.getInternalName(), "$classobj", exprType.getDescriptor()); } StackValue.onStack(exprType).put(type, v); @@ -1596,18 +1658,21 @@ public class ExpressionCodegen extends JetVisitor { cur = context; StackValue result = StackValue.local(0, TYPE_OBJECT); while (cur != null) { - if (cur instanceof CodegenContexts.MethodContext && !(cur instanceof CodegenContexts.ConstructorContext)) + if (cur instanceof CodegenContexts.MethodContext && !(cur instanceof CodegenContexts.ConstructorContext)) { cur = cur.getParentContext(); + } if (cur instanceof CodegenContexts.ScriptContext) { CodegenContexts.ScriptContext scriptContext = (CodegenContexts.ScriptContext) cur; - JvmClassName currentScriptClassName = state.getInjector().getClosureAnnotator().classNameForScriptDescriptor(scriptContext.getScriptDescriptor()); + JvmClassName currentScriptClassName = + state.getInjector().getClosureAnnotator().classNameForScriptDescriptor(scriptContext.getScriptDescriptor()); if (scriptContext.getScriptDescriptor() == receiver.getDeclarationDescriptor()) { result.put(currentScriptClassName.getAsmType(), v); } else { - JvmClassName className = state.getInjector().getClosureAnnotator().classNameForScriptDescriptor(receiver.getDeclarationDescriptor()); + JvmClassName className = + state.getInjector().getClosureAnnotator().classNameForScriptDescriptor(receiver.getDeclarationDescriptor()); String fieldName = state.getInjector().getScriptCodegen().getScriptFieldName(receiver.getDeclarationDescriptor()); result.put(currentScriptClassName.getAsmType(), v); StackValue.field(className.getAsmType(), currentScriptClassName, fieldName, false).put(className.getAsmType(), v); @@ -1629,13 +1694,14 @@ public class ExpressionCodegen extends JetVisitor { public StackValue generateThisOrOuter(@NotNull final ClassDescriptor calleeContainingClass) { PsiElement psiElement = BindingContextUtils.classDescriptorToDeclaration(bindingContext, calleeContainingClass); boolean isObject = psiElement instanceof JetClassOrObject && CodegenUtil.isNonLiteralObject((JetClassOrObject) psiElement); - + CodegenContext cur = context; Type type = asmType(calleeContainingClass.getDefaultType()); StackValue result = StackValue.local(0, type); while (cur != null) { - if (cur instanceof CodegenContexts.MethodContext && !(cur instanceof CodegenContexts.ConstructorContext)) + if (cur instanceof CodegenContexts.MethodContext && !(cur instanceof CodegenContexts.ConstructorContext)) { cur = cur.getParentContext(); + } if (DescriptorUtils.isSubclass(cur.getThisDescriptor(), calleeContainingClass)) { if (!isObject || (cur.getThisDescriptor() == calleeContainingClass)) { @@ -1653,7 +1719,7 @@ public class ExpressionCodegen extends JetVisitor { } cur = cur.getParentContext(); } - + throw new UnsupportedOperationException(); } @@ -1676,7 +1742,7 @@ public class ExpressionCodegen extends JetVisitor { } int index = 0; - int mask = 0; + int mask = 0; for (ValueParameterDescriptor valueParameterDescriptor : fd.getValueParameters()) { ResolvedValueArgument resolvedValueArgument = valueArguments.get(valueParameterDescriptor.getIndex()); @@ -1686,8 +1752,9 @@ public class ExpressionCodegen extends JetVisitor { } else if (resolvedValueArgument instanceof DefaultValueArgument) { Type type = valueParameterTypes.get(index); - if (type.getSort() == Type.OBJECT||type.getSort() == Type.ARRAY) + if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) { v.aconst(null); + } else if (type.getSort() == Type.FLOAT) { v.aconst(0f); } @@ -1724,7 +1791,7 @@ public class ExpressionCodegen extends JetVisitor { int size = arguments.size(); boolean hasSpread = false; - for(int i = 0; i != size; ++i) { + for (int i = 0; i != size; ++i) { if (arguments.get(i).getSpreadElement() != null) { hasSpread = true; break; @@ -1740,11 +1807,11 @@ public class ExpressionCodegen extends JetVisitor { v.anew(Type.getObjectType(owner)); v.dup(); v.invokespecial(owner, "", "()V"); - for(int i = 0; i != size; ++i) { + for (int i = 0; i != size; ++i) { v.dup(); ValueArgument argument = arguments.get(i); if (argument.getSpreadElement() != null) { - gen(argument.getArgumentExpression(),JetTypeMapper.TYPE_OBJECT); + gen(argument.getArgumentExpression(), JetTypeMapper.TYPE_OBJECT); v.invokevirtual(owner, "addSpread", "(Ljava/lang/Object;)V"); } else { @@ -1763,7 +1830,7 @@ public class ExpressionCodegen extends JetVisitor { else { v.iconst(arguments.size()); v.newarray(elementType); - for(int i = 0; i != size; ++i) { + for (int i = 0; i != size; ++i) { v.dup(); v.iconst(i); gen(arguments.get(i).getArgumentExpression(), elementType); @@ -1773,7 +1840,8 @@ public class ExpressionCodegen extends JetVisitor { } public int pushMethodArguments(JetCallElement expression, List valueParameterTypes) { - ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression()); + ResolvedCall resolvedCall = + bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression()); if (resolvedCall != null) { return pushMethodArguments(resolvedCall, valueParameterTypes); } @@ -1795,11 +1863,11 @@ public class ExpressionCodegen extends JetVisitor { public int indexOfLocal(JetReferenceExpression lhs) { final DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, lhs); if (typeMapper.isVarCapturedInClosure(declarationDescriptor)) { - return -1; + return -1; } return lookupLocal(declarationDescriptor); } - + @Override public StackValue visitDotQualifiedExpression(JetDotQualifiedExpression expression, StackValue receiver) { return genQualified(StackValue.none(), expression.getSelectorExpression()); @@ -1875,7 +1943,7 @@ public class ExpressionCodegen extends JetVisitor { return generateElvis(expression); } else if (opToken == JetTokens.IN_KEYWORD || opToken == JetTokens.NOT_IN) { - return generateIn (expression); + return generateIn(expression); } else { DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference()); @@ -1886,7 +1954,7 @@ public class ExpressionCodegen extends JetVisitor { Arrays.asList(expression.getLeft(), expression.getRight()), receiver, state); } else { - return invokeOperation(expression, (FunctionDescriptor)op, (CallableMethod) callable); + return invokeOperation(expression, (FunctionDescriptor) op, (CallableMethod) callable); } } } @@ -1901,10 +1969,11 @@ public class ExpressionCodegen extends JetVisitor { } else { StackValue leftValue = gen(expr); - FunctionDescriptor op = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference()); + FunctionDescriptor op = + (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference()); assert op != null; Type type = asmType(op.getValueParameters().get(0).getType()); - if(type.getSize() == 1) { + if (type.getSize() == 1) { leftValue.put(type, v); genToJVMStack(expression.getRight()); v.swap(); @@ -2015,7 +2084,9 @@ public class ExpressionCodegen extends JetVisitor { } if (isPrimitive(leftType)) // both are primitive + { return generateEqualsForExpressionsOnStack(opToken, leftType, rightType, false, false); + } assert leftJetType != null; assert rightJetType != null; @@ -2038,7 +2109,13 @@ public class ExpressionCodegen extends JetVisitor { return StackValue.onStack(Type.BOOLEAN_TYPE); } - public StackValue generateEqualsForExpressionsOnStack(IElementType opToken, Type leftType, Type rightType, boolean leftNullable, boolean rightNullable) { + public StackValue generateEqualsForExpressionsOnStack( + IElementType opToken, + Type leftType, + Type rightType, + boolean leftNullable, + boolean rightNullable + ) { if ((isNumberPrimitive(leftType) || leftType.getSort() == Type.BOOLEAN) && leftType == rightType) { return compareExpressionsOnStack(opToken, leftType); } @@ -2112,7 +2189,7 @@ public class ExpressionCodegen extends JetVisitor { JetType type = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression.getLeft()); assert type != null; final Type leftType = asmType(type); - if (type.isNullable()) { + if (type.isNullable()) { gen(expression.getLeft(), leftType); v.dup(); Label end = new Label(); @@ -2181,12 +2258,12 @@ public class ExpressionCodegen extends JetVisitor { final Callable callable = resolveToCallable((FunctionDescriptor) op, false); final JetExpression lhs = expression.getLeft(); -// if (lhs instanceof JetArrayAccessExpression) { -// JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) lhs; -// if (arrayAccessExpression.getIndexExpressions().size() != 1) { -// throw new UnsupportedOperationException("Augmented assignment with multi-index"); -// } -// } + // if (lhs instanceof JetArrayAccessExpression) { + // JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) lhs; + // if (arrayAccessExpression.getIndexExpressions().size() != 1) { + // throw new UnsupportedOperationException("Augmented assignment with multi-index"); + // } + // } Type lhsType = expressionType(lhs); //noinspection ConstantConditions @@ -2211,12 +2288,13 @@ public class ExpressionCodegen extends JetVisitor { final boolean keepReturnValue = !((FunctionDescriptor) op).getReturnType().equals(JetStandardClasses.getUnitType()); callAugAssignMethod(expression, (CallableMethod) callable, lhsType, keepReturnValue); } - + return StackValue.none(); } private void callAugAssignMethod(JetBinaryExpression expression, CallableMethod callable, Type lhsType, final boolean keepReturnValue) { - ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); + ResolvedCall resolvedCall = + bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); assert resolvedCall != null; StackValue value = gen(expression.getLeft()); @@ -2269,7 +2347,7 @@ public class ExpressionCodegen extends JetVisitor { public void invokeAppendMethod(Type exprType) { Method appendDescriptor = new Method("append", JL_STRING_BUILDER, - new Type[] { exprType.getSort() == Type.OBJECT ? TYPE_OBJECT : exprType}); + new Type[] {exprType.getSort() == Type.OBJECT ? TYPE_OBJECT : exprType}); v.invokevirtual("java/lang/StringBuilder", "append", appendDescriptor.getDescriptor()); } @@ -2283,7 +2361,7 @@ public class ExpressionCodegen extends JetVisitor { } return null; } - + @Override public StackValue visitPrefixExpression(JetPrefixExpression expression, StackValue receiver) { JetSimpleNameExpression operationSign = expression.getOperationReference(); @@ -2301,11 +2379,12 @@ public class ExpressionCodegen extends JetVisitor { else { DeclarationDescriptor cls = op.getContainingDeclaration(); CallableMethod callableMethod = (CallableMethod) callable; - if (isNumberPrimitive(cls) || !(op.getName().getName().equals("inc") || op.getName().getName().equals("dec")) ) { + if (isNumberPrimitive(cls) || !(op.getName().getName().equals("inc") || op.getName().getName().equals("dec"))) { return invokeOperation(expression, (FunctionDescriptor) op, callableMethod); } else { - ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); + ResolvedCall resolvedCall = + bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); assert resolvedCall != null; StackValue value = gen(expression.getBaseExpression()); @@ -2327,12 +2406,13 @@ public class ExpressionCodegen extends JetVisitor { if (functionLocalIndex >= 0) { stackValueForLocal(op, functionLocalIndex).put(ClosureCodegen.getInternalClassName(op).getAsmType(), v); } - ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); + ResolvedCall resolvedCall = + bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); assert resolvedCall != null; genThisAndReceiverFromResolvedCall(StackValue.none(), resolvedCall, callable); pushMethodArguments(resolvedCall, callable.getValueParameterTypes()); callable.invoke(v); - return returnValueAsStackValue(op, callable.getSignature().getAsmMethod().getReturnType()); + return returnValueAsStackValue(op, callable.getSignature().getAsmMethod().getReturnType()); } @Override @@ -2350,8 +2430,9 @@ public class ExpressionCodegen extends JetVisitor { v.mark(ok); return StackValue.onStack(base.type); } - else + else { return base; + } } DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference()); if (op instanceof FunctionDescriptor) { @@ -2373,7 +2454,8 @@ public class ExpressionCodegen extends JetVisitor { return StackValue.onStack(asmType); // old value } else { - ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); + ResolvedCall resolvedCall = + bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); assert resolvedCall != null; final Callable callable = resolveToCallable((FunctionDescriptor) op, false); @@ -2384,26 +2466,32 @@ public class ExpressionCodegen extends JetVisitor { Type type = expressionType(expression.getBaseExpression()); value.put(type, v); - switch(value.receiverSize()) { + switch (value.receiverSize()) { case 0: - if (type.getSize() == 2) + if (type.getSize() == 2) { v.dup2(); - else + } + else { v.dup(); - break; + } + break; case 1: - if (type.getSize() == 2) + if (type.getSize() == 2) { v.dup2X1(); - else + } + else { v.dupX1(); - break; + } + break; case 2: - if (type.getSize() == 2) + if (type.getSize() == 2) { v.dup2X2(); - else + } + else { v.dupX2(); + } break; case -1: @@ -2462,7 +2550,8 @@ public class ExpressionCodegen extends JetVisitor { if (property.isScriptDeclaration()) { JetScript scriptPsi = property.getScript(); JvmClassName scriptClassName = state.getInjector().getClosureAnnotator().classNameForScriptPsi(scriptPsi); - StackValue field = StackValue.field(typeMapper.mapType(variableDescriptor.getType(), MapTypeMode.VALUE), scriptClassName, property.getName(), false); + StackValue field = StackValue + .field(typeMapper.mapType(variableDescriptor.getType(), MapTypeMode.VALUE), scriptClassName, property.getName(), false); return StackValue.none(); } else { @@ -2474,7 +2563,6 @@ public class ExpressionCodegen extends JetVisitor { sharedVarType = typeMapper.getSharedVarType(variableDescriptor); assert variableDescriptor != null; - } Type varType = asmType(variableDescriptor.getType()); @@ -2500,13 +2588,18 @@ public class ExpressionCodegen extends JetVisitor { else { v.load(index, TYPE_OBJECT); gen(initializer, varType); - v.putfield(sharedVarType.getInternalName(), "ref", sharedVarType == TYPE_SHARED_VAR ? "Ljava/lang/Object;" : varType.getDescriptor()); + v.putfield(sharedVarType.getInternalName(), "ref", + sharedVarType == TYPE_SHARED_VAR ? "Ljava/lang/Object;" : varType.getDescriptor()); } } return StackValue.none(); } - private StackValue generateConstructorCall(JetCallExpression expression, JetSimpleNameExpression constructorReference, StackValue receiver) { + private StackValue generateConstructorCall( + JetCallExpression expression, + JetSimpleNameExpression constructorReference, + StackValue receiver + ) { DeclarationDescriptor constructorDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, constructorReference); final PsiElement declaration = BindingContextUtils.descriptorToDeclaration(bindingContext, constructorDescriptor); Type type; @@ -2533,7 +2626,9 @@ public class ExpressionCodegen extends JetVisitor { receiver.put(receiver.type, v); } - CallableMethod method = typeMapper.mapToCallableMethod((ConstructorDescriptor) constructorDescriptor, OwnerKind.IMPLEMENTATION, typeMapper.hasThis0(((ConstructorDescriptor) constructorDescriptor).getContainingDeclaration())); + CallableMethod method = typeMapper + .mapToCallableMethod((ConstructorDescriptor) constructorDescriptor, OwnerKind.IMPLEMENTATION, typeMapper + .hasThis0(((ConstructorDescriptor) constructorDescriptor).getContainingDeclaration())); invokeMethodWithArguments(method, expression, StackValue.none()); } } @@ -2563,15 +2658,16 @@ public class ExpressionCodegen extends JetVisitor { public void generateNewArray(JetCallExpression expression, JetType arrayType) { List args = new ArrayList(); - for(ValueArgument va : expression.getValueArguments()) + for (ValueArgument va : expression.getValueArguments()) { args.add(va.getArgumentExpression()); + } args.addAll(expression.getFunctionLiteralArguments()); boolean isArray = JetStandardLibraryNames.ARRAY.is(arrayType); if (isArray) { -// if (args.size() != 2 && !arrayType.getArguments().get(0).getType().isNullable()) { -// throw new CompilationException("array constructor of non-nullable type requires two arguments"); -// } + // if (args.size() != 2 && !arrayType.getArguments().get(0).getType().isNullable()) { + // throw new CompilationException("array constructor of non-nullable type requires two arguments"); + // } } else { if (args.size() != 1) { @@ -2590,8 +2686,8 @@ public class ExpressionCodegen extends JetVisitor { } if (args.size() == 2) { - int sizeIndex = myFrameMap.enterTemp(2); - int indexIndex = sizeIndex+1; + int sizeIndex = myFrameMap.enterTemp(2); + int indexIndex = sizeIndex + 1; v.dup(); v.arraylength(); @@ -2606,7 +2702,7 @@ public class ExpressionCodegen extends JetVisitor { Label end = new Label(); v.visitLabel(begin); v.load(indexIndex, Type.INT_TYPE); - v.load(sizeIndex, Type.INT_TYPE); + v.load(sizeIndex, Type.INT_TYPE); v.ificmpge(end); v.dup2(); @@ -2634,7 +2730,9 @@ public class ExpressionCodegen extends JetVisitor { final List indices = expression.getIndexExpressions(); FunctionDescriptor operationDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, expression); assert operationDescriptor != null; - if (arrayType.getSort() == Type.ARRAY && indices.size() == 1 && JetStandardLibraryNames.INT.is(operationDescriptor.getValueParameters().get(0).getType())) { + if (arrayType.getSort() == Type.ARRAY && + indices.size() == 1 && + JetStandardLibraryNames.INT.is(operationDescriptor.getValueParameters().get(0).getType())) { gen(array, arrayType); for (JetExpression index : indices) { gen(index, Type.INT_TYPE); @@ -2665,13 +2763,14 @@ public class ExpressionCodegen extends JetVisitor { int index = 0; if (isGetter) { Callable callable = resolveToCallable(getterDescriptor, false); - if (callable instanceof CallableMethod) + if (callable instanceof CallableMethod) { genThisAndReceiverFromResolvedCall(receiver, resolvedGetCall, (CallableMethod) callable); + } else { assert getterDescriptor != null; - gen(array, asmType(((ClassDescriptor)getterDescriptor.getContainingDeclaration()).getDefaultType())); + gen(array, asmType(((ClassDescriptor) getterDescriptor.getContainingDeclaration()).getDefaultType())); } - + assert getterDescriptor != null; if (getterDescriptor.getReceiverParameter().exists()) { index++; @@ -2684,13 +2783,14 @@ public class ExpressionCodegen extends JetVisitor { if (callable instanceof CallableMethod) { genThisAndReceiverFromResolvedCall(receiver, resolvedSetCall, (CallableMethod) callable); } - else + else { gen(array, arrayType); + } if (setterDescriptor.getReceiverParameter().exists()) { index++; } - asmType = argumentTypes[argumentTypes.length-1]; + asmType = argumentTypes[argumentTypes.length - 1]; } for (JetExpression jetExpression : expression.getIndexExpressions()) { @@ -2877,8 +2977,10 @@ The "returned" value of try expression with no finally is either the last expres } // on entering the function, expressionToMatch is already placed on stack, and we should consume it - private StackValue generatePatternMatch(JetPattern pattern, boolean negated, StackValue expressionToMatch, - boolean expressionToMatchIsNullable, @Nullable Label nextEntry) { + private StackValue generatePatternMatch( + JetPattern pattern, boolean negated, StackValue expressionToMatch, + boolean expressionToMatchIsNullable, @Nullable Label nextEntry + ) { if (pattern instanceof JetTypePattern) { JetTypeReference typeReference = ((JetTypePattern) pattern).getTypeReference(); JetType jetType = bindingContext.get(BindingContext.TYPE, typeReference); @@ -2911,7 +3013,8 @@ The "returned" value of try expression with no finally is either the last expres patternIsNullable = condJetType != null && condJetType.isNullable(); } gen(condExpression, condType); - return generateEqualsForExpressionsOnStack(JetTokens.EQEQ, subjectType, condType, expressionToMatchIsNullable, patternIsNullable); + return generateEqualsForExpressionsOnStack(JetTokens.EQEQ, subjectType, condType, expressionToMatchIsNullable, + patternIsNullable); } else { JetExpression condExpression = ((JetExpressionPattern) pattern).getExpression(); @@ -2938,8 +3041,10 @@ The "returned" value of try expression with no finally is either the last expres } } - private StackValue generateTuplePatternMatch(JetTuplePattern pattern, boolean negated, StackValue expressionToMatch, - @Nullable Label nextEntry) { + private StackValue generateTuplePatternMatch( + JetTuplePattern pattern, boolean negated, StackValue expressionToMatch, + @Nullable Label nextEntry + ) { final List entries = pattern.getEntries(); Label lblFail = new Label(); @@ -2969,7 +3074,7 @@ The "returned" value of try expression with no finally is either the last expres v.goTo(nextEntry); } else { - v.iconst(!negated?1:0); + v.iconst(!negated ? 1 : 0); } v.goTo(lblDone); v.mark(lblFail); @@ -2977,7 +3082,7 @@ The "returned" value of try expression with no finally is either the last expres v.goTo(nextEntry); } else { - v.iconst(negated?1:0); + v.iconst(negated ? 1 : 0); } v.mark(lblDone); return StackValue.onStack(Type.BOOLEAN_TYPE); @@ -3068,24 +3173,27 @@ The "returned" value of try expression with no finally is either the last expres return StackValue.onStack(resultType); } - private StackValue generateWhenCondition(Type subjectType, int subjectLocal, boolean subjectIsNullable, - JetWhenCondition condition, @Nullable Label nextEntry) { + private StackValue generateWhenCondition( + Type subjectType, int subjectLocal, boolean subjectIsNullable, + JetWhenCondition condition, @Nullable Label nextEntry + ) { if (condition instanceof JetWhenConditionInRange) { JetWhenConditionInRange conditionInRange = (JetWhenConditionInRange) condition; JetExpression rangeExpression = conditionInRange.getRangeExpression(); while (rangeExpression instanceof JetParenthesizedExpression) { - rangeExpression = ((JetParenthesizedExpression)rangeExpression).getExpression(); + rangeExpression = ((JetParenthesizedExpression) rangeExpression).getExpression(); } boolean inverted = conditionInRange.getOperationReference().getReferencedNameElementType() == JetTokens.NOT_IN; if (isIntRangeExpr(rangeExpression)) { getInIntRange(new StackValue.Local(subjectLocal, subjectType), (JetBinaryExpression) rangeExpression, inverted); } else { - FunctionDescriptor op = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, conditionInRange.getOperationReference()); + FunctionDescriptor op = + (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, conditionInRange.getOperationReference()); genToJVMStack(rangeExpression); new StackValue.Local(subjectLocal, subjectType).put(TYPE_OBJECT, v); invokeFunctionNoParams(op, Type.BOOLEAN_TYPE, v); - if(inverted) { + if (inverted) { invertBoolean(); } } @@ -3131,7 +3239,7 @@ The "returned" value of try expression with no finally is either the last expres } } } - return false ; + return false; } @Override diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 3a4218d912d..7044253cdce 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -84,8 +84,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (myClass instanceof JetClass) { JetClass jetClass = (JetClass) myClass; - if (jetClass.hasModifier(JetTokens.ABSTRACT_KEYWORD)) - isAbstract = true; + if (jetClass.hasModifier(JetTokens.ABSTRACT_KEYWORD)) { + isAbstract = true; + } if (jetClass.isTrait()) { isAbstract = true; isInterface = true; @@ -132,7 +133,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { access |= ACC_ENUM; } v.defineClass(myClass, V1_6, - access, + access, signature.getName(), signature.getJavaGenericSignature(), signature.getSuperclassName(), @@ -170,7 +171,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (descriptor.getClassObjectDescriptor() != null) { int innerClassAccess = ACC_PUBLIC | ACC_FINAL | ACC_STATIC; String outerClassInernalName = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName(); - v.visitInnerClass(outerClassInernalName + JvmAbi.CLASS_OBJECT_SUFFIX, outerClassInernalName, JvmAbi.CLASS_OBJECT_CLASS_NAME, innerClassAccess); + v.visitInnerClass(outerClassInernalName + JvmAbi.CLASS_OBJECT_SUFFIX, outerClassInernalName, JvmAbi.CLASS_OBJECT_CLASS_NAME, + innerClassAccess); } AnnotationCodegen.forClass(v.getVisitor(), typeMapper).genAnnotations(descriptor); @@ -209,7 +211,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { List typeParameters = descriptor.getTypeConstructor().getParameters(); typeMapper.writeFormalTypeParameters(typeParameters, signatureVisitor); } - + signatureVisitor.writeSupersStart(); { // superclass @@ -242,10 +244,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { superInterfaces = new ArrayList(superInterfacesLinkedHashSet); } - + signatureVisitor.writeSupersEnd(); - return new JvmClassSignature(jvmName(), superClass, superInterfaces, signatureVisitor.makeJavaString(), signatureVisitor.makeKotlinClassSignature()); + return new JvmClassSignature(jvmName(), superClass, superInterfaces, signatureVisitor.makeJavaString(), + signatureVisitor.makeKotlinClassSignature()); } private String jvmName() { @@ -261,8 +264,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { List delegationSpecifiers = myClass.getDelegationSpecifiers(); - if (myClass instanceof JetClass && ((JetClass) myClass).isTrait()) + if (myClass instanceof JetClass && ((JetClass) myClass).isTrait()) { return; + } if (kind != OwnerKind.IMPLEMENTATION) { throw new IllegalStateException("must be impl to reach this code: " + kind); @@ -281,10 +285,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } - if(superClassType == null) { - if (myClass instanceof JetClass && ((JetClass) myClass).hasModifier(JetTokens.ENUM_KEYWORD)) { + if (superClassType == null) { + if (descriptor.getKind() == ClassKind.ENUM_CLASS) { superClassType = JetStandardLibrary.getInstance().getEnumType(descriptor.getDefaultType()); - superClass = typeMapper.mapType(superClassType,MapTypeMode.VALUE).getInternalName(); + superClass = typeMapper.mapType(superClassType, MapTypeMode.VALUE).getInternalName(); + } + if (descriptor.getKind() == ClassKind.ENUM_ENTRY) { + superClassType = descriptor.getTypeConstructor().getSupertypes().iterator().next(); + superClass = typeMapper.mapType(superClassType, MapTypeMode.VALUE).getInternalName(); } } } @@ -300,10 +308,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { catch (CompilationException e) { throw e; } - catch(ProcessCanceledException e) { + catch (ProcessCanceledException e) { throw e; } - catch(RuntimeException e) { + catch (RuntimeException e) { throw new RuntimeException("Error generating primary constructor of class " + myClass.getName() + " with kind " + kind, e); } @@ -315,18 +323,20 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } private void generateEnumMethods() { - if(myEnumConstants.size() > 0) { + if (myEnumConstants.size() > 0) { { - Type type = typeMapper.mapType(JetStandardLibrary.getInstance().getArrayType(descriptor.getDefaultType()), MapTypeMode.IMPL); + Type type = + typeMapper.mapType(JetStandardLibrary.getInstance().getArrayType(descriptor.getDefaultType()), MapTypeMode.IMPL); MethodVisitor mv = v.newMethod(myClass, ACC_PUBLIC | ACC_STATIC, "values", "()" + type.getDescriptor(), null, null); mv.visitCode(); - mv.visitFieldInsn(GETSTATIC, typeMapper.mapType(descriptor.getDefaultType(),MapTypeMode.VALUE).getInternalName(), VALUES, type.getDescriptor()); + mv.visitFieldInsn(GETSTATIC, typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), VALUES, + type.getDescriptor()); mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), "clone", "()Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, type.getInternalName()); mv.visitInsn(ARETURN); - FunctionCodegen.endVisit(mv,"values()",myClass); + FunctionCodegen.endVisit(mv, "values()", myClass); } { Type type = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL); @@ -339,7 +349,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { mv.visitMethodInsn(INVOKESTATIC, "java/lang/Enum", "valueOf", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;"); mv.visitTypeInsn(CHECKCAST, type.getInternalName()); mv.visitInsn(ARETURN); - FunctionCodegen.endVisit(mv,"values()",myClass); + FunctionCodegen.endVisit(mv, "values()", myClass); } } } @@ -393,10 +403,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { Method method = typeMapper.mapGetterSignature(bridge, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); JvmPropertyAccessorSignature originalSignature = typeMapper.mapGetterSignature(original, OwnerKind.IMPLEMENTATION); Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod(); - MethodVisitor mv = v.newMethod(null, ACC_BRIDGE | ACC_SYNTHETIC | ACC_STATIC, method.getName(), method.getDescriptor(), null, null); + MethodVisitor mv = + v.newMethod(null, ACC_BRIDGE | ACC_SYNTHETIC | ACC_STATIC, method.getName(), method.getDescriptor(), null, null); PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature(), originalSignature.getJvmMethodSignature().getKotlinTypeParameter(), - original, ((PropertyDescriptor) entry.getValue()).getGetter().getVisibility()); + original, + ((PropertyDescriptor) entry.getValue()).getGetter().getVisibility()); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { StubCodegen.generateStubCode(mv); } @@ -406,25 +418,30 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { InstructionAdapter iv = new InstructionAdapter(mv); iv.load(0, JetTypeMapper.TYPE_OBJECT); - if (original.getVisibility() == Visibilities.PRIVATE) - iv.getfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), original.getName().getName(), originalMethod.getReturnType().getDescriptor()); - else - iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), originalMethod.getName(), originalMethod.getDescriptor()); + if (original.getVisibility() == Visibilities.PRIVATE) { + iv.getfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), original.getName().getName(), + originalMethod.getReturnType().getDescriptor()); + } + else { + iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), + originalMethod.getName(), originalMethod.getDescriptor()); + } iv.areturn(method.getReturnType()); FunctionCodegen.endVisit(iv, "accessor", null); } } - if (bridge.isVar()) - { + if (bridge.isVar()) { Method method = typeMapper.mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); JvmPropertyAccessorSignature originalSignature2 = typeMapper.mapSetterSignature(original, OwnerKind.IMPLEMENTATION); Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod(); - MethodVisitor mv = v.newMethod(null, ACC_STATIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null); + MethodVisitor mv = + v.newMethod(null, ACC_STATIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null); PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature(), originalSignature2.getJvmMethodSignature().getKotlinTypeParameter(), - original, ((PropertyDescriptor) entry.getValue()).getSetter().getVisibility()); + original, + ((PropertyDescriptor) entry.getValue()).getSetter().getVisibility()); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { StubCodegen.generateStubCode(mv); } @@ -441,10 +458,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { //noinspection AssignmentToForLoopParameter reg += argType.getSize(); } - if (original.getVisibility() == Visibilities.PRIVATE && original.getModality() == Modality.FINAL) - iv.putfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), original.getName().getName(), originalMethod.getArgumentTypes()[0].getDescriptor()); - else - iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), originalMethod.getName(), originalMethod.getDescriptor()); + if (original.getVisibility() == Visibilities.PRIVATE && original.getModality() == Modality.FINAL) { + iv.putfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), original.getName().getName(), + originalMethod.getArgumentTypes()[0].getDescriptor()); + } + else { + iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), + originalMethod.getName(), originalMethod.getDescriptor()); + } iv.areturn(method.getReturnType()); FunctionCodegen.endVisit(iv, "accessor", null); @@ -471,7 +492,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { v.putstatic(name, "$instance", typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getDescriptor()); } }); - } } @@ -500,9 +520,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { protected void generatePrimaryConstructor() { if (myClass instanceof JetClass) { - JetClass aClass = (JetClass)myClass; - if (aClass.isTrait()) + JetClass aClass = (JetClass) myClass; + if (aClass.isTrait()) { return; + } if (aClass.isAnnotation()) { return; } @@ -521,27 +542,32 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { boolean hasThis0 = typeMapper.hasThis0(descriptor); if (constructorDescriptor == null) { BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, false); - + signatureWriter.writeFormalTypeParametersStart(); signatureWriter.writeFormalTypeParametersEnd(); - + signatureWriter.writeParametersStart(); - + if (hasThis0) { signatureWriter.writeParameterType(JvmMethodParameterKind.THIS0); - typeMapper.mapType(typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor).getDefaultType(), signatureWriter, MapTypeMode.VALUE); + typeMapper + .mapType(typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor).getDefaultType(), signatureWriter, + MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } signatureWriter.writeParametersEnd(); - + signatureWriter.writeVoidReturn(); constructorMethod = signatureWriter.makeJvmMethodSignature(""); - callableMethod = new CallableMethod(JvmClassName.byInternalName("Ignored"), null, null, constructorMethod, INVOKESPECIAL, null, null, null); + callableMethod = + new CallableMethod(JvmClassName.byInternalName("Ignored"), null, null, constructorMethod, INVOKESPECIAL, null, null, + null); } else { - callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind, typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration())); + callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind, + typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration())); constructorMethod = callableMethod.getSignature(); } @@ -566,22 +592,28 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ObjectOrClosureCodegen closure = context.closure; int firstSuperArgument = -1; - final LinkedList consArgTypes = new LinkedList(constructorMethod.getKotlinParameterTypes()); + final LinkedList consArgTypes = + new LinkedList(constructorMethod.getKotlinParameterTypes()); int insert = 0; if (closure != null) { if (closure.captureThis != null) { - if (!hasThis0) - consArgTypes.add(insert, new JvmMethodParameterSignature(Type.getObjectType(context.getThisDescriptor().getName().getName()), "", JvmMethodParameterKind.THIS0)); + if (!hasThis0) { + consArgTypes.add(insert, + new JvmMethodParameterSignature(Type.getObjectType(context.getThisDescriptor().getName().getName()), + "", JvmMethodParameterKind.THIS0)); + } insert++; } else { - if (hasThis0) + if (hasThis0) { insert++; + } } - if (closure.captureReceiver != null) + if (closure.captureReceiver != null) { consArgTypes.add(insert++, new JvmMethodParameterSignature(closure.captureReceiver, "", JvmMethodParameterKind.RECEIVER)); + } for (DeclarationDescriptor descriptor : closure.closure.keySet()) { if (descriptor instanceof VariableDescriptor && !(descriptor instanceof PropertyDescriptor)) { @@ -591,7 +623,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { type = sharedVarType; } else { - type = state.getInjector().getJetTypeMapper().mapType(((VariableDescriptor) descriptor).getType(), MapTypeMode.VALUE); + type = state.getInjector().getJetTypeMapper() + .mapType(((VariableDescriptor) descriptor).getType(), MapTypeMode.VALUE); } consArgTypes.add(insert++, new JvmMethodParameterSignature(type, "", JvmMethodParameterKind.SHARED_VAR)); } @@ -603,16 +636,20 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (myClass instanceof JetObjectDeclaration && ((JetObjectDeclaration) myClass).isObjectLiteral()) { if (superCall instanceof JetDelegatorToSuperCall) { - if (closure != null) + if (closure != null) { closure.superCall = (JetDelegatorToSuperCall) superCall; - DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression()); + } + DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, + ((JetDelegatorToSuperCall) superCall).getCalleeExpression() + .getConstructorReferenceExpression()); if (declarationDescriptor instanceof ClassDescriptor) { declarationDescriptor = ((ClassDescriptorFromSource) declarationDescriptor).getUnsubstitutedPrimaryConstructor(); } ConstructorDescriptor superConstructor = (ConstructorDescriptor) declarationDescriptor; - CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, typeMapper.hasThis0(superConstructor.getContainingDeclaration())); + CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, typeMapper + .hasThis0(superConstructor.getContainingDeclaration())); firstSuperArgument = insert; - for(Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) { + for (Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) { consArgTypes.add(insert++, new JvmMethodParameterSignature(t, "", JvmMethodParameterKind.SHARED_VAR)); } } @@ -621,7 +658,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } int flags = JetTypeMapper.getAccessModifiers(constructorDescriptor, 0); - final MethodVisitor mv = v.newMethod(myClass, flags, constructorMethod.getName(), constructorMethod.getAsmMethod().getDescriptor(), constructorMethod.getGenericsSignature(), null); + final MethodVisitor mv = v.newMethod(myClass, flags, constructorMethod.getName(), constructorMethod.getAsmMethod().getDescriptor(), + constructorMethod.getGenericsSignature(), null); if (state.getClassBuilderMode() == ClassBuilderMode.SIGNATURES) return; AnnotationVisitor jetConstructorVisitor = mv.visitAnnotation(JvmStdlibNames.JET_CONSTRUCTOR.getDescriptor(), true); @@ -632,7 +670,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } jetConstructorVisitor.visitEnd(); - + AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(constructorDescriptor); if (constructorDescriptor != null) { @@ -642,13 +680,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { i++; } - if(myClass instanceof JetClass && ((JetClass)myClass).hasModifier(JetTokens.ENUM_KEYWORD)) { + if (descriptor.getKind() == ClassKind.ENUM_CLASS || descriptor.getKind() == ClassKind.ENUM_ENTRY) { i += 2; } for (ValueParameterDescriptor valueParameter : constructorDescriptor.getValueParameters()) { AnnotationCodegen.forParameter(i, mv, state.getInjector().getJetTypeMapper()).genAnnotations(valueParameter); - JetValueParameterAnnotationWriter jetValueParameterAnnotation = JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i); + JetValueParameterAnnotationWriter jetValueParameterAnnotation = + JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i); jetValueParameterAnnotation.writeName(valueParameter.getName().getName()); jetValueParameterAnnotation.writeHasDefaultValue(valueParameter.declaresDefaultValue()); jetValueParameterAnnotation.writeType(constructorMethod.getKotlinParameterType(i)); @@ -665,20 +704,20 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { mv.visitCode(); List paramDescrs = constructorDescriptor != null - ? constructorDescriptor.getValueParameters() - : Collections.emptyList(); + ? constructorDescriptor.getValueParameters() + : Collections.emptyList(); ConstructorFrameMap frameMap = new ConstructorFrameMap(callableMethod, constructorDescriptor, hasThis0); final InstructionAdapter iv = new InstructionAdapter(mv); ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, constructorContext, state); -// for(int slot = 0; slot != frameMap.getTypeParameterCount(); ++slot) { -// if (constructorDescriptor != null) -// codegen.addTypeParameter(constructorDescriptor.getTypeParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO)); -// else -// codegen.addTypeParameter(descriptor.getTypeConstructor().getParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO)); -// } + // for(int slot = 0; slot != frameMap.getTypeParameterCount(); ++slot) { + // if (constructorDescriptor != null) + // codegen.addTypeParameter(constructorDescriptor.getTypeParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO)); + // else + // codegen.addTypeParameter(descriptor.getTypeConstructor().getParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO)); + // } Type classType = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL); JvmClassName classname = JvmClassName.byType(classType); @@ -694,7 +733,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (superCall == null) { iv.load(0, Type.getType("L" + superClass + ";")); - if(descriptor.getKind() == ClassKind.ENUM_CLASS) { + if (descriptor.getKind() == ClassKind.ENUM_CLASS || descriptor.getKind() == ClassKind.ENUM_ENTRY) { iv.load(1, JetTypeMapper.JL_STRING_TYPE); iv.load(2, Type.INT_TYPE); iv.invokespecial(superClass, "", "(Ljava/lang/String;I)V"); @@ -711,14 +750,20 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); if (typeMapper.hasThis0(superClassDescriptor)) { iv.load(1, JetTypeMapper.TYPE_OBJECT); - parameterTypes.add(typeMapper.mapType(typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor).getDefaultType(), MapTypeMode.VALUE)); + parameterTypes.add(typeMapper.mapType( + typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor).getDefaultType(), MapTypeMode.VALUE)); } Method superCallMethod = new Method("", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()])); - iv.invokespecial(typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "", superCallMethod.getDescriptor()); + iv.invokespecial(typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "", + superCallMethod.getDescriptor()); } else { - ConstructorDescriptor constructorDescriptor1 = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression()); - generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) superCall, constructorDescriptor1, frameMap, firstSuperArgument); + ConstructorDescriptor constructorDescriptor1 = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, + ((JetDelegatorToSuperCall) superCall) + .getCalleeExpression() + .getConstructorReferenceExpression()); + generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) superCall, constructorDescriptor1, frameMap, + firstSuperArgument); } final ClassDescriptor outerDescriptor = typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor); @@ -738,7 +783,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (closure.captureReceiver != null) { iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(1, closure.captureReceiver); - iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "receiver$0", closure.captureReceiver.getDescriptor()); + iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "receiver$0", + closure.captureReceiver.getDescriptor()); k += closure.captureReceiver.getSize(); } @@ -752,7 +798,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(k, StackValue.refType(sharedVarType)); k += StackValue.refType(sharedVarType).getSize(); - iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "$" + varDescr.getName(), sharedVarType.getDescriptor()); + iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), + "$" + varDescr.getName(), sharedVarType.getDescriptor()); l++; } } @@ -760,8 +807,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { int n = 0; for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) { - if (specifier == superCall) + if (specifier == superCall) { continue; + } if (specifier instanceof JetDelegatorByExpressionSpecifier) { iv.load(0, classType); @@ -779,8 +827,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { JetClass superClass = (JetClass) BindingContextUtils.classDescriptorToDeclaration(bindingContext, superClassDescriptor); final CodegenContext delegateContext = context.intoClass(superClassDescriptor, - new OwnerKind.DelegateKind(StackValue.field(fieldType, classname, delegateField, false), - typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName()), state.getInjector().getJetTypeMapper()); + new OwnerKind.DelegateKind(StackValue.field(fieldType, classname, + delegateField, false), + typeMapper.mapType(superClassDescriptor + .getDefaultType(), + MapTypeMode.IMPL) + .getInternalName()), + state.getInjector().getJetTypeMapper()); generateDelegates(superClass, delegateContext, field); } } @@ -803,13 +856,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { mv.visitInsn(RETURN); FunctionCodegen.endVisit(mv, "constructor", myClass); - FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod.getAsmMethod(), constructorDescriptor, OwnerKind.IMPLEMENTATION); + FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod.getAsmMethod(), constructorDescriptor, + OwnerKind.IMPLEMENTATION); } private void generateTraitMethods() { - if (myClass instanceof JetClass && (((JetClass)myClass).isTrait() || ((JetClass)myClass).hasModifier(JetTokens.ABSTRACT_KEYWORD))) + if (myClass instanceof JetClass && + (((JetClass) myClass).isTrait() || ((JetClass) myClass).hasModifier(JetTokens.ABSTRACT_KEYWORD))) { return; - + } + for (Pair needDelegates : getTraitImplementations(descriptor)) { CallableMemberDescriptor callableDescriptor = needDelegates.first; if (needDelegates.second instanceof SimpleFunctionDescriptor) { @@ -843,11 +899,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { PropertyDescriptor property = ((PropertyAccessorDescriptor) fun).getCorrespondingProperty(); if (fun instanceof PropertyGetterDescriptor) { function = typeMapper.mapGetterSignature(property, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); - functionOriginal = typeMapper.mapGetterSignature(property.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); + functionOriginal = + typeMapper.mapGetterSignature(property.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature() + .getAsmMethod(); } else if (fun instanceof PropertySetterDescriptor) { function = typeMapper.mapSetterSignature(property, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); - functionOriginal = typeMapper.mapSetterSignature(property.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); + functionOriginal = + typeMapper.mapSetterSignature(property.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature() + .getAsmMethod(); } else { throw new IllegalStateException("Accessor is neither getter, nor setter, what is it?"); @@ -861,14 +921,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { final MethodVisitor mv = v.newMethod(myClass, flags, function.getName(), function.getDescriptor(), null, null); AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(fun); - JvmMethodSignature jvmSignature = typeMapper.mapToCallableMethod(inheritedFun, false, OwnerKind.IMPLEMENTATION).getSignature(); + JvmMethodSignature jvmSignature = + typeMapper.mapToCallableMethod(inheritedFun, false, OwnerKind.IMPLEMENTATION).getSignature(); JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv); BitSet kotlinFlags = CodegenUtil.getFlagsForVisibility(fun.getVisibility()); if (fun instanceof PropertyAccessorDescriptor) { kotlinFlags.set(JvmStdlibNames.FLAG_PROPERTY_BIT); aw.writeTypeParameters(jvmSignature.getKotlinTypeParameter()); aw.writePropertyType(jvmSignature.getKotlinReturnType()); - } else { + } + else { aw.writeNullableReturnType(fun.getReturnType().isNullable()); aw.writeTypeParameters(jvmSignature.getKotlinTypeParameter()); aw.writeReturnType(jvmSignature.getKotlinReturnType()); @@ -882,7 +944,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { mv.visitCode(); FrameMap frameMap = context.prepareFrame(state.getInjector().getJetTypeMapper()); - ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getAsmMethod().getReturnType(), context, state); + ExpressionCodegen codegen = + new ExpressionCodegen(mv, frameMap, jvmSignature.getAsmMethod().getReturnType(), context, state); codegen.generateThisOrOuter(descriptor); // ??? wouldn't it be a good idea to put it? Type[] argTypes = function.getArgumentTypes(); @@ -904,10 +967,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { type = typeMapper.mapType(jetType, MapTypeMode.IMPL); } - String fdescriptor = functionOriginal.getDescriptor().replace("(","(" + type.getDescriptor()); - Type type1 = typeMapper.mapType(((ClassDescriptor) fun.getContainingDeclaration()).getDefaultType(), MapTypeMode.TRAIT_IMPL); + String fdescriptor = functionOriginal.getDescriptor().replace("(", "(" + type.getDescriptor()); + Type type1 = + typeMapper.mapType(((ClassDescriptor) fun.getContainingDeclaration()).getDefaultType(), MapTypeMode.TRAIT_IMPL); iv.invokestatic(type1.getInternalName(), function.getName(), fdescriptor); - if (function.getReturnType().getSort() == Type.OBJECT && !function.getReturnType().equals(functionOriginal.getReturnType())) { + if (function.getReturnType().getSort() == Type.OBJECT && + !function.getReturnType().equals(functionOriginal.getReturnType())) { iv.checkcast(function.getReturnType()); } iv.areturn(function.getReturnType()); @@ -919,28 +984,38 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } - private void generateDelegatorToConstructorCall(InstructionAdapter iv, ExpressionCodegen codegen, JetCallElement constructorCall, - ConstructorDescriptor constructorDescriptor, - ConstructorFrameMap frameMap, int firstSuperArgument) { + private void generateDelegatorToConstructorCall( + InstructionAdapter iv, ExpressionCodegen codegen, JetCallElement constructorCall, + ConstructorDescriptor constructorDescriptor, + ConstructorFrameMap frameMap, int firstSuperArgument + ) { ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration(); iv.load(0, TYPE_OBJECT); - if(classDecl.getKind() == ClassKind.ENUM_CLASS) { + if (classDecl.getKind() == ClassKind.ENUM_CLASS || classDecl.getKind() == ClassKind.ENUM_ENTRY) { iv.load(1, JetTypeMapper.TYPE_OBJECT); iv.load(2, Type.INT_TYPE); } if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) { - iv.load(frameMap.getOuterThisIndex(), typeMapper.mapType(((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), MapTypeMode.IMPL)); + iv.load(frameMap.getOuterThisIndex(), + typeMapper.mapType(((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), MapTypeMode.IMPL)); } - CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, kind, typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration())); + CallableMethod method = typeMapper + .mapToCallableMethod(constructorDescriptor, kind, typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration())); - if (myClass instanceof JetObjectDeclaration && superCall instanceof JetDelegatorToSuperCall && ((JetObjectDeclaration) myClass).isObjectLiteral()) { - ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression()); - CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, typeMapper.hasThis0(superConstructor.getContainingDeclaration())); - int nextVar = firstSuperArgument+1; - for(Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) { + if (myClass instanceof JetObjectDeclaration && + superCall instanceof JetDelegatorToSuperCall && + ((JetObjectDeclaration) myClass).isObjectLiteral()) { + ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, + ((JetDelegatorToSuperCall) superCall) + .getCalleeExpression() + .getConstructorReferenceExpression()); + CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, + typeMapper.hasThis0(superConstructor.getContainingDeclaration())); + int nextVar = firstSuperArgument + 1; + for (Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) { iv.load(nextVar, t); nextVar += t.getSize(); } @@ -999,7 +1074,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.iconst(ordinal); // TODO type and constructor parameters - String implClass = typeMapper.mapType(myType, MapTypeMode.IMPL).getInternalName(); + ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, enumConstant); + String implClass = typeMapper.mapType(classDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName(); final List delegationSpecifiers = enumConstant.getDelegationSpecifiers(); if (delegationSpecifiers.size() > 1) { @@ -1016,8 +1092,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { final JetDelegationSpecifier specifier = delegationSpecifiers.get(0); if (specifier instanceof JetDelegatorToSuperCall) { final JetDelegatorToSuperCall superCall = (JetDelegatorToSuperCall) specifier; - ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression()); - CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, OwnerKind.IMPLEMENTATION, typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration())); + ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) bindingContext + .get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression()); + CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, OwnerKind.IMPLEMENTATION, typeMapper + .hasThis0(constructorDescriptor.getContainingDeclaration())); codegen.invokeMethodWithArguments(method, superCall, StackValue.none()); } else { @@ -1028,14 +1106,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.invokespecial(implClass, "", "(Ljava/lang/String;I)V"); } iv.dup(); - iv.putstatic(implClass, enumConstant.getName(), "L" + implClass + ";"); + iv.putstatic(myAsmType.getInternalName(), enumConstant.getName(), "L" + myAsmType.getInternalName() + ";"); iv.astore(TYPE_OBJECT); } iv.putstatic(myAsmType.getInternalName(), "$VALUES", arrayAsmType.getDescriptor()); } - public static void generateInitializers(@NotNull ExpressionCodegen codegen, @NotNull InstructionAdapter iv, @NotNull List declarations, - @NotNull BindingContext bindingContext, @NotNull JetTypeMapper typeMapper) { + public static void generateInitializers( + @NotNull ExpressionCodegen codegen, @NotNull InstructionAdapter iv, @NotNull List declarations, + @NotNull BindingContext bindingContext, @NotNull JetTypeMapper typeMapper + ) { for (JetDeclaration declaration : declarations) { if (declaration instanceof JetProperty) { final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.get(BindingContext.VARIABLE, declaration); @@ -1048,34 +1128,44 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { Object value = compileTimeValue.getValue(); Type type = typeMapper.mapType(propertyDescriptor.getType(), MapTypeMode.VALUE); if (JetTypeMapper.isPrimitive(type)) { - if ( !propertyDescriptor.getType().isNullable() && value instanceof Number) { - if (type == Type.INT_TYPE && ((Number)value).intValue() == 0) + if (!propertyDescriptor.getType().isNullable() && value instanceof Number) { + if (type == Type.INT_TYPE && ((Number) value).intValue() == 0) { continue; - if (type == Type.BYTE_TYPE && ((Number)value).byteValue() == 0) + } + if (type == Type.BYTE_TYPE && ((Number) value).byteValue() == 0) { continue; - if (type == Type.LONG_TYPE && ((Number)value).longValue() == 0L) + } + if (type == Type.LONG_TYPE && ((Number) value).longValue() == 0L) { continue; - if (type == Type.SHORT_TYPE && ((Number)value).shortValue() == 0) + } + if (type == Type.SHORT_TYPE && ((Number) value).shortValue() == 0) { continue; - if (type == Type.DOUBLE_TYPE && ((Number)value).doubleValue() == 0d) + } + if (type == Type.DOUBLE_TYPE && ((Number) value).doubleValue() == 0d) { continue; - if (type == Type.FLOAT_TYPE && ((Number)value).byteValue() == 0f) + } + if (type == Type.FLOAT_TYPE && ((Number) value).byteValue() == 0f) { continue; + } } - if (type == Type.BOOLEAN_TYPE && value instanceof Boolean && !((Boolean)value)) + if (type == Type.BOOLEAN_TYPE && value instanceof Boolean && !((Boolean) value)) { continue; - if (type == Type.CHAR_TYPE && value instanceof Character && ((Character)value) == 0) + } + if (type == Type.CHAR_TYPE && value instanceof Character && ((Character) value) == 0) { continue; + } } else { - if (value == null) + if (value == null) { continue; + } } } iv.load(0, JetTypeMapper.TYPE_OBJECT); Type type = codegen.expressionType(initializer); - if (propertyDescriptor.getType().isNullable()) + if (propertyDescriptor.getType().isNullable()) { type = JetTypeMapper.boxType(type); + } codegen.gen(initializer, type); // @todo write directly to the field. Fix test excloset.jet::test6 JvmClassName owner = typeMapper.getOwner(propertyDescriptor, OwnerKind.IMPLEMENTATION); @@ -1083,7 +1173,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { StackValue.property(propertyDescriptor.getName().getName(), owner, owner, propType, false, false, false, null, null, 0).store(propType, iv); } - } } else if (declaration instanceof JetClassInitializer) { @@ -1105,7 +1194,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { for (CallableMemberDescriptor overriddenDescriptor : overriddenDescriptors) { if (overriddenDescriptor.getContainingDeclaration() == classDescriptor) { if (declaration instanceof PropertyDescriptor) { - propertyCodegen.genDelegate((PropertyDescriptor) declaration, (PropertyDescriptor) overriddenDescriptor, field); + propertyCodegen + .genDelegate((PropertyDescriptor) declaration, (PropertyDescriptor) overriddenDescriptor, field); } else if (declaration instanceof SimpleFunctionDescriptor) { functionCodegen.genDelegate((SimpleFunctionDescriptor) declaration, overriddenDescriptor, field); @@ -1129,7 +1219,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { */ public static List> getTraitImplementations(@NotNull ClassDescriptor classDescriptor) { List> r = Lists.newArrayList(); - + root: for (DeclarationDescriptor decl : classDescriptor.getDefaultType().getMemberScope().getAllDescriptors()) { if (!(decl instanceof CallableMemberDescriptor)) { @@ -1141,7 +1231,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { continue; } - Collection overriddenDeclarations = OverridingUtil.getOverriddenDeclarations(callableMemberDescriptor); + Collection overriddenDeclarations = + OverridingUtil.getOverriddenDeclarations(callableMemberDescriptor); for (CallableMemberDescriptor overriddenDeclaration : overriddenDeclarations) { if (overriddenDeclaration.getModality() != Modality.ABSTRACT) { if (!CodegenUtil.isInterface(overriddenDeclaration.getContainingDeclaration())) { @@ -1149,7 +1240,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } } - + for (CallableMemberDescriptor overriddenDeclaration : overriddenDeclarations) { if (overriddenDeclaration.getModality() != Modality.ABSTRACT) { r.add(Pair.create(callableMemberDescriptor, overriddenDeclaration)); @@ -1159,5 +1250,4 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { return r; } - } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index a86ab093492..b41adfb3fb7 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -306,11 +306,13 @@ public class JetTypeMapper { return JvmClassName.byInternalName(r.toString()); } - @NotNull public Type mapReturnType(@NotNull final JetType jetType) { + @NotNull + public Type mapReturnType(@NotNull final JetType jetType) { return mapReturnType(jetType, null); } - @NotNull private Type mapReturnType(@NotNull final JetType jetType, @Nullable BothSignatureWriter signatureVisitor) { + @NotNull + private Type mapReturnType(@NotNull final JetType jetType, @Nullable BothSignatureWriter signatureVisitor) { if (jetType.equals(JetStandardClasses.getUnitType())) { if (signatureVisitor != null) { signatureVisitor.writeAsmType(Type.VOID_TYPE, false); @@ -375,7 +377,12 @@ public class JetTypeMapper { } } else if (klass.getKind() == ClassKind.ENUM_ENTRY) { - return getJvmInternalFQName(klass.getContainingDeclaration()); + if (closureAnnotator.enumEntryNeedSubclass(klass)) { + return getJvmInternalFQName(klass.getContainingDeclaration()) + "$" + klass.getName().getName(); + } + else { + return getJvmInternalFQName(klass.getContainingDeclaration()); + } } } @@ -462,13 +469,13 @@ public class JetTypeMapper { } if (descriptor instanceof ClassDescriptor - && JetStandardLibraryNames.ARRAY.is((ClassDescriptor) descriptor) - && mapBuiltinsToJava) { + && JetStandardLibraryNames.ARRAY.is((ClassDescriptor) descriptor) + && mapBuiltinsToJava) { if (jetType.getArguments().size() != 1) { throw new UnsupportedOperationException("arrays must have one type argument"); } JetType memberType = jetType.getArguments().get(0).getType(); - + if (signatureVisitor != null) { signatureVisitor.writeArrayType(jetType.isNullable()); mapType(memberType, signatureVisitor, MapTypeMode.TYPE_PARAMETER); @@ -511,7 +518,8 @@ public class JetTypeMapper { Type type = mapType(((TypeParameterDescriptor) descriptor).getUpperBoundsAsType(), kind); if (signatureVisitor != null) { - TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) jetType.getConstructor().getDeclarationDescriptor(); + TypeParameterDescriptor typeParameterDescriptor = + (TypeParameterDescriptor) jetType.getConstructor().getDeclarationDescriptor(); assert typeParameterDescriptor != null; signatureVisitor.writeTypeVariable(typeParameterDescriptor.getName(), jetType.isNullable(), type); } @@ -584,11 +592,13 @@ public class JetTypeMapper { } public CallableMethod mapToCallableMethod(FunctionDescriptor functionDescriptor, boolean superCall, OwnerKind kind) { - if (functionDescriptor == null) { return null; } + if (functionDescriptor == null) { + return null; + } final DeclarationDescriptor functionParent = functionDescriptor.getOriginal().getContainingDeclaration(); - while(functionDescriptor.getKind()==CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { + while (functionDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { functionDescriptor = functionDescriptor.getOverriddenDescriptors().iterator().next(); } @@ -614,11 +624,12 @@ public class JetTypeMapper { thisClass = null; } else if (functionParent instanceof ScriptDescriptor) { - thisClass = owner = ownerForDefaultParam = ownerForDefaultImpl = closureAnnotator.classNameForScriptDescriptor((ScriptDescriptor) functionParent); + thisClass = owner = + ownerForDefaultParam = ownerForDefaultImpl = closureAnnotator.classNameForScriptDescriptor((ScriptDescriptor) functionParent); invokeOpcode = INVOKEVIRTUAL; } else if (functionParent instanceof ClassDescriptor) { - + FunctionDescriptor declarationFunctionDescriptor = findAnyDeclaration(functionDescriptor); ClassDescriptor currentOwner = (ClassDescriptor) functionParent; @@ -647,8 +658,8 @@ public class JetTypeMapper { ownerForDefaultParam.getInternalName() + (originalIsInterface ? JvmAbi.TRAIT_IMPL_SUFFIX : "")); invokeOpcode = isInterface - ? (superCall ? Opcodes.INVOKESTATIC : Opcodes.INVOKEINTERFACE) - : (isAccessor ? Opcodes.INVOKESTATIC : (superCall ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL)); + ? (superCall ? Opcodes.INVOKESTATIC : Opcodes.INVOKEINTERFACE) + : (isAccessor ? Opcodes.INVOKESTATIC : (superCall ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL)); if (isInterface && superCall) { descriptor = mapSignature(functionDescriptor, false, OwnerKind.TRAIT_IMPL); owner = JvmClassName.byInternalName(owner.getInternalName() + JvmAbi.TRAIT_IMPL_SUFFIX); @@ -673,7 +684,9 @@ public class JetTypeMapper { } private static boolean isAccessor(FunctionDescriptor functionDescriptor) { - return functionDescriptor instanceof AccessorForFunctionDescriptor || functionDescriptor instanceof AccessorForPropertyDescriptor.Getter || functionDescriptor instanceof AccessorForPropertyDescriptor.Setter; + return functionDescriptor instanceof AccessorForFunctionDescriptor || + functionDescriptor instanceof AccessorForPropertyDescriptor.Getter || + functionDescriptor instanceof AccessorForPropertyDescriptor.Setter; } @NotNull @@ -689,11 +702,11 @@ public class JetTypeMapper { } private JvmMethodSignature mapSignature(FunctionDescriptor f, boolean needGenericSignature, OwnerKind kind) { - + if (kind == OwnerKind.TRAIT_IMPL) { needGenericSignature = false; } - + BothSignatureWriter signatureVisitor = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, needGenericSignature); writeFormalTypeParameters(f.getTypeParameters(), signatureVisitor); @@ -704,9 +717,9 @@ public class JetTypeMapper { signatureVisitor.writeParametersStart(); - if(isAccessor(f)) { + if (isAccessor(f)) { signatureVisitor.writeParameterType(JvmMethodParameterKind.THIS); - mapType(((ClassifierDescriptor)f.getContainingDeclaration()).getDefaultType(), signatureVisitor, MapTypeMode.VALUE); + mapType(((ClassifierDescriptor) f.getContainingDeclaration()).getDefaultType(), signatureVisitor, MapTypeMode.VALUE); signatureVisitor.writeParameterTypeEnd(); } @@ -714,11 +727,11 @@ public class JetTypeMapper { ClassDescriptor containingDeclaration = (ClassDescriptor) f.getContainingDeclaration(); JetType jetType = TraitImplBodyCodegen.getSuperClass(containingDeclaration); Type type = mapType(jetType, MapTypeMode.VALUE); - if(type.getInternalName().equals("java/lang/Object")) { + if (type.getInternalName().equals("java/lang/Object")) { jetType = containingDeclaration.getDefaultType(); type = mapType(jetType, MapTypeMode.VALUE); } - + signatureVisitor.writeParameterType(JvmMethodParameterKind.THIS); signatureVisitor.writeAsmType(type, jetType.isNullable()); signatureVisitor.writeParameterTypeEnd(); @@ -763,7 +776,8 @@ public class JetTypeMapper { } private void writeFormalTypeParameter(TypeParameterDescriptor typeParameterDescriptor, BothSignatureWriter signatureVisitor) { - signatureVisitor.writeFormalTypeParameter(typeParameterDescriptor.getName().getName(), typeParameterDescriptor.getVariance(), typeParameterDescriptor.isReified()); + signatureVisitor.writeFormalTypeParameter(typeParameterDescriptor.getName().getName(), typeParameterDescriptor.getVariance(), + typeParameterDescriptor.isReified()); classBound: { @@ -799,23 +813,22 @@ public class JetTypeMapper { signatureVisitor.writeInterfaceBoundEnd(); } } - - signatureVisitor.writeFormalTypeParameterEnd(); + signatureVisitor.writeFormalTypeParameterEnd(); } public JvmMethodSignature mapSignature(Name name, FunctionDescriptor f) { final ReceiverDescriptor receiver = f.getReceiverParameter(); - + BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, false); - + writeFormalTypeParameters(f.getTypeParameters(), signatureWriter); signatureWriter.writeParametersStart(); - if(isAccessor(f)) { + if (isAccessor(f)) { signatureWriter.writeParameterType(JvmMethodParameterKind.THIS); - mapType(((ClassifierDescriptor)f.getContainingDeclaration()).getDefaultType(), signatureWriter, MapTypeMode.VALUE); + mapType(((ClassifierDescriptor) f.getContainingDeclaration()).getDefaultType(), signatureWriter, MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } @@ -832,15 +845,15 @@ public class JetTypeMapper { } signatureWriter.writeParametersEnd(); - + signatureWriter.writeReturnType(); mapReturnType(f.getReturnType(), signatureWriter); signatureWriter.writeReturnTypeEnd(); - + return signatureWriter.makeJvmMethodSignature(name.getName()); } - + public JvmPropertyAccessorSignature mapGetterSignature(PropertyDescriptor descriptor, OwnerKind kind) { final DeclarationDescriptor parentDescriptor = descriptor.getContainingDeclaration(); boolean isAnnotation = parentDescriptor instanceof ClassDescriptor && @@ -854,16 +867,17 @@ public class JetTypeMapper { signatureWriter.writeParametersStart(); - if(kind == OwnerKind.TRAIT_IMPL) { + if (kind == OwnerKind.TRAIT_IMPL) { ClassDescriptor containingDeclaration = (ClassDescriptor) parentDescriptor; signatureWriter.writeParameterType(JvmMethodParameterKind.THIS); mapType(containingDeclaration.getDefaultType(), signatureWriter, MapTypeMode.IMPL); signatureWriter.writeParameterTypeEnd(); } else { - if(descriptor instanceof AccessorForPropertyDescriptor) { + if (descriptor instanceof AccessorForPropertyDescriptor) { signatureWriter.writeParameterType(JvmMethodParameterKind.THIS); - mapType(((ClassifierDescriptor)descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter, MapTypeMode.VALUE); + mapType(((ClassifierDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter, + MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } } @@ -893,7 +907,7 @@ public class JetTypeMapper { // TODO: generics signature is not always needed BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, true); - + writeFormalTypeParameters(descriptor.getTypeParameters(), signatureWriter); JetType outType = descriptor.getType(); @@ -908,9 +922,10 @@ public class JetTypeMapper { signatureWriter.writeParameterTypeEnd(); } else { - if(descriptor instanceof AccessorForPropertyDescriptor) { + if (descriptor instanceof AccessorForPropertyDescriptor) { signatureWriter.writeParameterType(JvmMethodParameterKind.THIS); - mapType(((ClassifierDescriptor)descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter, MapTypeMode.VALUE); + mapType(((ClassifierDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter, + MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } } @@ -924,19 +939,20 @@ public class JetTypeMapper { signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE); mapType(outType, signatureWriter, MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); - + signatureWriter.writeParametersEnd(); - + signatureWriter.writeVoidReturn(); JvmMethodSignature jvmMethodSignature = signatureWriter.makeJvmMethodSignature(name); - return new JvmPropertyAccessorSignature(jvmMethodSignature, jvmMethodSignature.getKotlinParameterType(jvmMethodSignature.getParameterCount() - 1)); + return new JvmPropertyAccessorSignature(jvmMethodSignature, + jvmMethodSignature.getKotlinParameterType(jvmMethodSignature.getParameterCount() - 1)); } private JvmMethodSignature mapConstructorSignature(ConstructorDescriptor descriptor, boolean hasThis0) { - + BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, true); - + List parameters = descriptor.getOriginal().getValueParameters(); // constructor type parmeters are fake @@ -947,11 +963,12 @@ public class JetTypeMapper { ClassDescriptor containingDeclaration = descriptor.getContainingDeclaration(); if (hasThis0) { signatureWriter.writeParameterType(JvmMethodParameterKind.THIS0); - mapType(closureAnnotator.getEclosingClassDescriptor(containingDeclaration).getDefaultType(), signatureWriter, MapTypeMode.VALUE); + mapType(closureAnnotator.getEclosingClassDescriptor(containingDeclaration).getDefaultType(), signatureWriter, + MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } - if(containingDeclaration.getKind() == ClassKind.ENUM_CLASS) { + if (containingDeclaration.getKind() == ClassKind.ENUM_CLASS || containingDeclaration.getKind() == ClassKind.ENUM_ENTRY) { signatureWriter.writeParameterType(JvmMethodParameterKind.ENUM_NAME); mapType(JetStandardLibrary.getInstance().getStringType(), signatureWriter, MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); @@ -965,9 +982,9 @@ public class JetTypeMapper { mapType(parameter.getType(), signatureWriter, MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } - + signatureWriter.writeParametersEnd(); - + signatureWriter.writeVoidReturn(); return signatureWriter.makeJvmMethodSignature(""); @@ -983,7 +1000,8 @@ public class JetTypeMapper { for (ScriptDescriptor importedScript : importedScripts) { signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE); - mapType(closureAnnotator.classDescriptorForScriptDescriptor(importedScript).getDefaultType(), signatureWriter, MapTypeMode.VALUE); + mapType(closureAnnotator.classDescriptorForScriptDescriptor(importedScript).getDefaultType(), signatureWriter, + MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } @@ -1055,28 +1073,31 @@ public class JetTypeMapper { private static boolean isForceReal(JvmClassName className) { return JvmPrimitiveType.getByWrapperClass(className) != null - || className.getFqName().getFqName().equals("java.lang.String") - || className.getFqName().getFqName().equals("java.lang.CharSequence") - || className.getFqName().getFqName().equals("java.lang.Object") - || className.getFqName().getFqName().equals("java.lang.Number") - || className.getFqName().getFqName().equals("java.lang.Enum") - || className.getFqName().getFqName().equals("java.lang.Comparable"); + || className.getFqName().getFqName().equals("java.lang.String") + || className.getFqName().getFqName().equals("java.lang.CharSequence") + || className.getFqName().getFqName().equals("java.lang.Object") + || className.getFqName().getFqName().equals("java.lang.Number") + || className.getFqName().getFqName().equals("java.lang.Enum") + || className.getFqName().getFqName().equals("java.lang.Comparable"); } public static boolean isGenericsArray(JetType type) { - return JetStandardLibraryNames.ARRAY.is(type) && type.getArguments().get(0).getType().getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor; + return JetStandardLibraryNames.ARRAY.is(type) && + type.getArguments().get(0).getType().getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor; } public Type getSharedVarType(DeclarationDescriptor descriptor) { if (descriptor instanceof PropertyDescriptor) { - return StackValue.sharedTypeForType(mapType(((PropertyDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE)); + return StackValue + .sharedTypeForType(mapType(((PropertyDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE)); } else if (descriptor instanceof SimpleFunctionDescriptor && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) { PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor); return closureAnnotator.classNameForAnonymousClass((JetElement) psiElement).getAsmType(); } else if (descriptor instanceof FunctionDescriptor) { - return StackValue.sharedTypeForType(mapType(((FunctionDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE)); + return StackValue + .sharedTypeForType(mapType(((FunctionDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE)); } else if (descriptor instanceof VariableDescriptor && isVarCapturedInClosure(descriptor)) { JetType outType = ((VariableDescriptor) descriptor).getType(); diff --git a/compiler/testData/codegen/enum/abstractmethod.kt b/compiler/testData/codegen/enum/abstractmethod.kt new file mode 100644 index 00000000000..8c00de1fae6 --- /dev/null +++ b/compiler/testData/codegen/enum/abstractmethod.kt @@ -0,0 +1,10 @@ +fun box() = IssueState.DEFAULT.ToString() + IssueState.FIXED.ToString() + +open enum class IssueState { + DEFAULT + FIXED { + override fun ToString() = "K" + } + + open fun ToString() : String = "O" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java index be46d8de8cd..516195f6664 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java @@ -100,4 +100,35 @@ public class EnumGenTest extends CodegenTestCase { public void testInClassObj() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { blackBoxFile("enum/inclassobj.kt"); } + + public void testAbstractMethod() + throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { + blackBoxFile("enum/abstractmethod.kt"); + } + + public void testNoClassForSimpleEnum() + throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException { + loadFile("enum/name.kt"); + Class cls = loadImplementationClass(generateClassesInFile(), "State"); + Field field = cls.getField("O"); + assertEquals("State", field.get(null).getClass().getName()); + } + + public void testYesClassForComplexEnum() + throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException { + loadFile("enum/abstractmethod.kt"); + Class cls = loadImplementationClass(generateClassesInFile(), "IssueState"); + Field field = cls.getField("DEFAULT"); + assertEquals("IssueState", field.get(null).getClass().getName()); + field = cls.getField("FIXED"); + assertEquals("IssueState", field.getType().getName()); + assertEquals("IssueState$FIXED", field.get(null).getClass().getName()); + assertNotNull(cls.getClassLoader().loadClass("IssueState$FIXED")); + try { + cls.getClassLoader().loadClass("IssueState$DEFAULT"); + fail(); + } + catch (ClassNotFoundException e) { + } + } } From 813c7d0871afc688fa831782bc768c92763b8410 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Wed, 15 Aug 2012 16:06:06 +0300 Subject: [PATCH 31/36] test for obsolete KT-1119 & proper final flag for enum class with entries overriding methods/properties --- .../jet/codegen/ImplementationBodyCodegen.java | 7 +++++++ compiler/testData/codegen/regressions/kt1119.kt | 11 +++++++++++ .../tests/org/jetbrains/jet/codegen/EnumGenTest.java | 4 ++++ 3 files changed, 22 insertions(+) create mode 100644 compiler/testData/codegen/regressions/kt1119.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 7044253cdce..7504e3542f6 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -130,6 +130,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { access |= ACC_ANNOTATION; } if (isEnum) { + for (JetDeclaration declaration : myClass.getDeclarations()) { + if (declaration instanceof JetEnumEntry) { + if (state.getInjector().getClosureAnnotator().enumEntryNeedSubclass((JetEnumEntry) declaration)) { + access &= ~ACC_FINAL; + } + } + } access |= ACC_ENUM; } v.defineClass(myClass, V1_6, diff --git a/compiler/testData/codegen/regressions/kt1119.kt b/compiler/testData/codegen/regressions/kt1119.kt new file mode 100644 index 00000000000..9c371666f30 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt1119.kt @@ -0,0 +1,11 @@ +enum class Direction() { + NORTH { + val someSpecialValue = "OK" + } + + SOUTH + WEST + EAST +} + +fun box() = Direction.NORTH.someSpecialValue diff --git a/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java index 516195f6664..c57ea2dae7a 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java @@ -131,4 +131,8 @@ public class EnumGenTest extends CodegenTestCase { catch (ClassNotFoundException e) { } } + + public void testKt1119() { + blackBoxFile("regressions/kt1119.kt"); + } } From ca33712b002ff9e2a65475102b1f57a00fb09b4c Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Wed, 15 Aug 2012 17:08:43 +0300 Subject: [PATCH 32/36] making code greener and properly formatted --- .../All_Jvm_Backend_Tests.xml | 6 + .../AccessorForFunctionDescriptor.java | 2 +- .../AccessorForPropertyDescriptor.java | 2 +- .../jet/codegen/AnnotationCodegen.java | 60 ++-- .../jetbrains/jet/codegen/CallableMethod.java | 24 +- .../jet/codegen/ClassBodyCodegen.java | 11 +- .../jetbrains/jet/codegen/ClassBuilder.java | 54 ++-- .../jet/codegen/ClassBuilderFactories.java | 2 +- .../jet/codegen/ClassBuilderFactory.java | 8 +- .../jet/codegen/ClassBuilderMode.java | 16 +- .../jetbrains/jet/codegen/ClassCodegen.java | 1 - .../jet/codegen/ClassFileFactory.java | 4 +- .../jetbrains/jet/codegen/ClosureCodegen.java | 84 +++--- .../jetbrains/jet/codegen/CodegenContext.java | 59 ++-- .../jet/codegen/CodegenContexts.java | 104 ++++--- .../jetbrains/jet/codegen/CodegenUtil.java | 24 +- .../jet/codegen/CompilationErrorHandler.java | 2 +- .../jet/codegen/CompilationException.java | 9 +- .../jet/codegen/ConstructorFrameMap.java | 7 +- .../jet/codegen/ExpressionCodegen.java | 12 +- .../org/jetbrains/jet/codegen/FrameMap.java | 9 +- .../jet/codegen/FunctionCodegen.java | 207 +++++++++----- .../GeneratedAnonymousClassDescriptor.java | 6 +- .../jet/codegen/GeneratedClassLoader.java | 8 +- .../jet/codegen/GenerationState.java | 40 ++- .../codegen/ImplementationBodyCodegen.java | 39 ++- .../jetbrains/jet/codegen/JetTypeMapper.java | 21 +- .../jetbrains/jet/codegen/MapTypeMode.java | 16 +- .../jetbrains/jet/codegen/MemberCodegen.java | 7 +- .../jet/codegen/NamespaceCodegen.java | 47 ++-- .../jet/codegen/ObjectOrClosureCodegen.java | 19 +- .../org/jetbrains/jet/codegen/OwnerKind.java | 8 +- .../jet/codegen/ProjectionErasingJetType.java | 84 ------ .../jet/codegen/PropertyCodegen.java | 97 ++++--- .../jetbrains/jet/codegen/ScriptCodegen.java | 60 ++-- .../org/jetbrains/jet/codegen/StackValue.java | 257 ++++++++++++------ .../jetbrains/jet/codegen/StubCodegen.java | 11 +- .../jet/codegen/TraitImplBodyCodegen.java | 2 +- .../jet/codegen/intrinsics/ArrayGet.java | 14 +- .../jet/codegen/intrinsics/ArrayIndices.java | 14 +- .../jet/codegen/intrinsics/ArrayIterator.java | 14 +- .../jet/codegen/intrinsics/ArraySet.java | 14 +- .../jet/codegen/intrinsics/ArraySize.java | 14 +- .../jet/codegen/intrinsics/BinaryOp.java | 16 +- .../jet/codegen/intrinsics/CompareTo.java | 17 +- .../jet/codegen/intrinsics/Concat.java | 14 +- .../jet/codegen/intrinsics/EmptyRange.java | 6 +- .../jet/codegen/intrinsics/EnumValueOf.java | 21 +- .../jet/codegen/intrinsics/EnumValues.java | 20 +- .../jet/codegen/intrinsics/Equals.java | 26 +- .../jet/codegen/intrinsics/HashCode.java | 6 +- .../codegen/intrinsics/IdentityEquals.java | 18 +- .../jet/codegen/intrinsics/Increment.java | 22 +- .../codegen/intrinsics/IntrinsicMethod.java | 10 +- .../codegen/intrinsics/IntrinsicMethods.java | 47 ++-- .../jet/codegen/intrinsics/IntrinsicsMap.java | 5 +- .../jetbrains/jet/codegen/intrinsics/Inv.java | 14 +- .../codegen/intrinsics/IteratorIterator.java | 14 +- .../jet/codegen/intrinsics/IteratorNext.java | 41 ++- .../codegen/intrinsics/JavaClassArray.java | 27 +- .../codegen/intrinsics/JavaClassFunction.java | 19 +- .../codegen/intrinsics/JavaClassProperty.java | 14 +- .../jet/codegen/intrinsics/NewArray.java | 17 +- .../jetbrains/jet/codegen/intrinsics/Not.java | 14 +- .../jet/codegen/intrinsics/NumberCast.java | 14 +- .../jet/codegen/intrinsics/PsiMethodCall.java | 13 +- .../jet/codegen/intrinsics/RangeTo.java | 38 ++- .../jet/codegen/intrinsics/StringGetChar.java | 20 +- .../jet/codegen/intrinsics/StringLength.java | 14 +- .../jet/codegen/intrinsics/StringPlus.java | 14 +- .../jet/codegen/intrinsics/StupidSync.java | 16 +- .../jet/codegen/intrinsics/Sure.java | 21 +- .../jet/codegen/intrinsics/ToString.java | 14 +- .../jet/codegen/intrinsics/UnaryMinus.java | 14 +- .../jet/codegen/intrinsics/UnaryPlus.java | 17 +- .../signature/BothSignatureWriter.java | 81 +++--- .../codegen/signature/JvmClassSignature.java | 6 +- .../signature/JvmMethodParameterKind.java | 2 - .../JvmMethodParameterSignature.java | 3 +- .../codegen/signature/JvmMethodSignature.java | 34 ++- .../JvmPropertyAccessorSignature.java | 1 - .../kotlin/JetMethodAnnotationWriter.java | 8 +- .../JetValueParameterAnnotationWriter.java | 2 +- 83 files changed, 1353 insertions(+), 866 deletions(-) delete mode 100644 compiler/backend/src/org/jetbrains/jet/codegen/ProjectionErasingJetType.java diff --git a/.idea/runConfigurations/All_Jvm_Backend_Tests.xml b/.idea/runConfigurations/All_Jvm_Backend_Tests.xml index 4270bdf9050..e83bbdb5e13 100644 --- a/.idea/runConfigurations/All_Jvm_Backend_Tests.xml +++ b/.idea/runConfigurations/All_Jvm_Backend_Tests.xml @@ -23,7 +23,13 @@ + + + diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AccessorForFunctionDescriptor.java b/compiler/backend/src/org/jetbrains/jet/codegen/AccessorForFunctionDescriptor.java index 87735e64197..1f7160d83cf 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AccessorForFunctionDescriptor.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AccessorForFunctionDescriptor.java @@ -24,7 +24,7 @@ import java.util.Collections; /** * @author alex.tkachman -*/ + */ public class AccessorForFunctionDescriptor extends SimpleFunctionDescriptorImpl { public AccessorForFunctionDescriptor(DeclarationDescriptor descriptor, DeclarationDescriptor containingDeclaration, int index) { super(containingDeclaration, Collections.emptyList(), diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AccessorForPropertyDescriptor.java b/compiler/backend/src/org/jetbrains/jet/codegen/AccessorForPropertyDescriptor.java index fad288fc832..1b10d5984c1 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AccessorForPropertyDescriptor.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AccessorForPropertyDescriptor.java @@ -25,7 +25,7 @@ import java.util.Collections; /** * @author alex.tkachman -*/ + */ public class AccessorForPropertyDescriptor extends PropertyDescriptor { public AccessorForPropertyDescriptor(PropertyDescriptor pd, DeclarationDescriptor containingDeclaration, int index) { super(containingDeclaration, Collections.emptyList(), Modality.FINAL, Visibilities.PUBLIC, diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java index ade7c42458c..3a647608f89 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java @@ -17,6 +17,10 @@ package org.jetbrains.jet.codegen; import com.intellij.psi.PsiElement; +import org.jetbrains.asm4.AnnotationVisitor; +import org.jetbrains.asm4.ClassVisitor; +import org.jetbrains.asm4.FieldVisitor; +import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.Annotated; @@ -24,11 +28,13 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; -import org.jetbrains.jet.lang.resolve.calls.*; +import org.jetbrains.jet.lang.resolve.calls.DefaultValueArgument; +import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; +import org.jetbrains.jet.lang.resolve.calls.ResolvedValueArgument; +import org.jetbrains.jet.lang.resolve.calls.VarargValueArgument; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.asm4.*; import java.lang.annotation.RetentionPolicy; import java.util.List; @@ -47,28 +53,32 @@ public abstract class AnnotationCodegen { } public void genAnnotations(Annotated annotated) { - if (annotated == null) + if (annotated == null) { return; - - if (!(annotated instanceof DeclarationDescriptor)) + } + + if (!(annotated instanceof DeclarationDescriptor)) { return; + } PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(bindingContext, (DeclarationDescriptor) annotated); JetModifierList modifierList = null; if (annotated instanceof ConstructorDescriptor && psiElement instanceof JetClass) { - modifierList = ((JetClass)psiElement).getPrimaryConstructorModifierList(); + modifierList = ((JetClass) psiElement).getPrimaryConstructorModifierList(); } else if (psiElement instanceof JetModifierListOwner) { modifierList = ((JetModifierListOwner) psiElement).getModifierList(); } - if (modifierList == null) + if (modifierList == null) { return; + } List annotationEntries = modifierList.getAnnotationEntries(); for (JetAnnotationEntry annotationEntry : annotationEntries) { - ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, annotationEntry.getCalleeExpression()); + ResolvedCall resolvedCall = + bindingContext.get(BindingContext.RESOLVED_CALL, annotationEntry.getCalleeExpression()); assert resolvedCall != null; AnnotationDescriptor annotationDescriptor = bindingContext.get(BindingContext.ANNOTATION, annotationEntry); @@ -79,8 +89,10 @@ public abstract class AnnotationCodegen { } } - private void genAnnotation(ResolvedCall resolvedCall, - JetType type) { + private void genAnnotation( + ResolvedCall resolvedCall, + JetType type + ) { ClassifierDescriptor classifierDescriptor = type.getConstructor().getDeclarationDescriptor(); RetentionPolicy rp = getRetentionPolicy(classifierDescriptor, typeMapper); if (rp == RetentionPolicy.SOURCE) { @@ -117,7 +129,7 @@ public abstract class AnnotationCodegen { visitor.visitEnd(); } else { - assert valueArguments.size() == 1 : "Number of arguments on " + keyName + " = " + valueArguments.size(); // todo + assert valueArguments.size() == 1 : "Number of arguments on " + keyName + " = " + valueArguments.size(); // todo JetExpression expression = valueArguments.get(0).getArgumentExpression(); genAnnotationExpressionValue(annotationVisitor, keyName, expression); } @@ -125,7 +137,7 @@ public abstract class AnnotationCodegen { private void genAnnotationExpressionValue(AnnotationVisitor annotationVisitor, String keyName, JetExpression expression) { CompileTimeConstant compileTimeConstant = - bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expression); + bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expression); if (compileTimeConstant != null) { Object value = compileTimeConstant.getValue(); @@ -134,40 +146,42 @@ public abstract class AnnotationCodegen { } if (expression instanceof JetDotQualifiedExpression) { - JetDotQualifiedExpression qualifiedExpression = (JetDotQualifiedExpression)expression; + JetDotQualifiedExpression qualifiedExpression = (JetDotQualifiedExpression) expression; ResolvedCall call = - bindingContext.get(BindingContext.RESOLVED_CALL, qualifiedExpression.getSelectorExpression()); + bindingContext.get(BindingContext.RESOLVED_CALL, qualifiedExpression.getSelectorExpression()); if (call != null) { if (call.getResultingDescriptor() instanceof PropertyDescriptor) { - PropertyDescriptor descriptor = (PropertyDescriptor)call.getResultingDescriptor(); - annotationVisitor.visitEnum(keyName, typeMapper.mapType(descriptor.getReturnType(), MapTypeMode.VALUE).getDescriptor(), descriptor.getName().getName()); + PropertyDescriptor descriptor = (PropertyDescriptor) call.getResultingDescriptor(); + annotationVisitor.visitEnum(keyName, typeMapper.mapType(descriptor.getReturnType(), MapTypeMode.VALUE).getDescriptor(), + descriptor.getName().getName()); return; } } } else { if (expression instanceof JetCallExpression) { - JetCallExpression callExpression = (JetCallExpression)expression; + JetCallExpression callExpression = (JetCallExpression) expression; ResolvedCall call = - bindingContext.get(BindingContext.RESOLVED_CALL, callExpression.getCalleeExpression()); + bindingContext.get(BindingContext.RESOLVED_CALL, callExpression.getCalleeExpression()); if (call != null) { List annotations = call.getResultingDescriptor().getOriginal().getAnnotations(); String value = null; if (annotations != null) { for (AnnotationDescriptor annotation : annotations) { - if("Intrinsic".equals(annotation.getType().getConstructor().getDeclarationDescriptor().getName().getName())) { + if ("Intrinsic".equals(annotation.getType().getConstructor().getDeclarationDescriptor().getName().getName())) { value = (String) annotation.getValueArguments().get(0).getValue(); break; } } } if (IntrinsicMethods.KOTLIN_JAVA_CLASS_FUNCTION.equals(value)) { - annotationVisitor.visit(keyName, typeMapper.mapType(call.getResultingDescriptor().getReturnType().getArguments().get(0).getType(), MapTypeMode.VALUE)); + annotationVisitor.visit(keyName, typeMapper + .mapType(call.getResultingDescriptor().getReturnType().getArguments().get(0).getType(), MapTypeMode.VALUE)); return; } else if (IntrinsicMethods.KOTLIN_ARRAYS_ARRAY.equals(value)) { AnnotationVisitor visitor = annotationVisitor.visitArray(keyName); - VarargValueArgument next = (VarargValueArgument)call.getValueArguments().values().iterator().next(); + VarargValueArgument next = (VarargValueArgument) call.getValueArguments().values().iterator().next(); for (ValueArgument argument : next.getArguments()) { genAnnotationExpressionValue(visitor, null, argument.getArgumentExpression()); } @@ -175,9 +189,9 @@ public abstract class AnnotationCodegen { return; } else if (call.getResultingDescriptor() instanceof ConstructorDescriptor) { - ConstructorDescriptor descriptor = (ConstructorDescriptor)call.getResultingDescriptor(); + ConstructorDescriptor descriptor = (ConstructorDescriptor) call.getResultingDescriptor(); AnnotationVisitor visitor = annotationVisitor.visitAnnotation(keyName, typeMapper - .mapType(descriptor.getContainingDeclaration().getDefaultType(), MapTypeMode.VALUE).getDescriptor()); + .mapType(descriptor.getContainingDeclaration().getDefaultType(), MapTypeMode.VALUE).getDescriptor()); getAnnotation(call, visitor); visitor.visitEnd(); return; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java b/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java index 4137ddfd573..dd473c62916 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java @@ -18,14 +18,12 @@ package org.jetbrains.jet.codegen; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.codegen.signature.JvmMethodSignature; -import org.jetbrains.jet.lang.descriptors.CallableDescriptor; -import org.jetbrains.jet.lang.resolve.java.JvmAbi; -import org.jetbrains.jet.lang.resolve.java.JvmClassName; -import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.asm4.Opcodes; import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; +import org.jetbrains.jet.codegen.signature.JvmMethodSignature; +import org.jetbrains.jet.lang.resolve.java.JvmAbi; +import org.jetbrains.jet.lang.resolve.java.JvmClassName; import java.util.List; @@ -49,9 +47,11 @@ public class CallableMethod implements Callable { @Nullable private final Type generateCalleeType; - public CallableMethod(@NotNull JvmClassName owner, @Nullable JvmClassName defaultImplOwner, @Nullable JvmClassName defaultImplParam, + public CallableMethod( + @NotNull JvmClassName owner, @Nullable JvmClassName defaultImplOwner, @Nullable JvmClassName defaultImplParam, JvmMethodSignature signature, int invokeOpcode, - @Nullable JvmClassName thisClass, @Nullable Type receiverParameterType, @Nullable Type generateCalleeType) { + @Nullable JvmClassName thisClass, @Nullable Type receiverParameterType, @Nullable Type generateCalleeType + ) { this.owner = owner; this.defaultImplOwner = defaultImplOwner; this.defaultImplParam = defaultImplParam; @@ -93,7 +93,8 @@ public class CallableMethod implements Callable { } void invoke(InstructionAdapter v) { - v.visitMethodInsn(getInvokeOpcode(), owner.getInternalName(), getSignature().getAsmMethod().getName(), getSignature().getAsmMethod().getDescriptor()); + v.visitMethodInsn(getInvokeOpcode(), owner.getInternalName(), getSignature().getAsmMethod().getName(), + getSignature().getAsmMethod().getDescriptor()); } @Nullable @@ -108,14 +109,15 @@ public class CallableMethod implements Callable { v.iconst(mask); String desc = getSignature().getAsmMethod().getDescriptor().replace(")", "I)"); - if("".equals(getSignature().getAsmMethod().getName())) { + if ("".equals(getSignature().getAsmMethod().getName())) { v.visitMethodInsn(Opcodes.INVOKESPECIAL, defaultImplOwner.getInternalName(), "", desc); } else { - if (getInvokeOpcode() != Opcodes.INVOKESTATIC) + if (getInvokeOpcode() != Opcodes.INVOKESTATIC) { desc = desc.replace("(", "(" + defaultImplParam.getDescriptor()); + } v.visitMethodInsn(Opcodes.INVOKESTATIC, defaultImplOwner.getInternalName(), - getSignature().getAsmMethod().getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, desc); + getSignature().getAsmMethod().getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, desc); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java index 167a0fe6d11..f47f323b70b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java @@ -90,17 +90,18 @@ public abstract class ClassBodyCodegen { } private void generatePrimaryConstructorProperties(PropertyCodegen propertyCodegen, JetClassOrObject origin) { - boolean isAnnotation = origin instanceof JetClass && ((JetClass)origin).isAnnotation(); - OwnerKind kind = context.getContextKind(); + boolean isAnnotation = origin instanceof JetClass && ((JetClass) origin).isAnnotation(); for (JetParameter p : getPrimaryConstructorParameters()) { if (p.getValOrVarNode() != null) { PropertyDescriptor propertyDescriptor = state.getBindingContext().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, p); if (propertyDescriptor != null) { if (!isAnnotation) { propertyCodegen.generateBackingField(p, propertyDescriptor); - propertyCodegen.generateDefaultGetter(propertyDescriptor, JetTypeMapper.getAccessModifiers(propertyDescriptor,0), p); + propertyCodegen + .generateDefaultGetter(propertyDescriptor, JetTypeMapper.getAccessModifiers(propertyDescriptor, 0), p); if (propertyDescriptor.isVar()) { - propertyCodegen.generateDefaultSetter(propertyDescriptor, JetTypeMapper.getAccessModifiers(propertyDescriptor,0), p); + propertyCodegen + .generateDefaultSetter(propertyDescriptor, JetTypeMapper.getAccessModifiers(propertyDescriptor, 0), p); } } else { @@ -121,7 +122,7 @@ public abstract class ClassBodyCodegen { private void generateStaticInitializer() { if (staticInitializerChunks.size() > 0) { - final MethodVisitor mv = v.newMethod(null, ACC_PUBLIC | Opcodes.ACC_STATIC,"", "()V", null, null); + final MethodVisitor mv = v.newMethod(null, ACC_PUBLIC | Opcodes.ACC_STATIC, "", "()V", null, null); if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { mv.visitCode(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilder.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilder.java index 1f220128517..82818e8533a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilder.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilder.java @@ -21,11 +21,7 @@ package org.jetbrains.jet.codegen; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.Nullable; -import org.jetbrains.asm4.AnnotationVisitor; -import org.jetbrains.asm4.ClassVisitor; -import org.jetbrains.asm4.FieldVisitor; -import org.jetbrains.asm4.MethodVisitor; -import org.jetbrains.asm4.Opcodes; +import org.jetbrains.asm4.*; public abstract class ClassBuilder { public static class Concrete extends ClassBuilder { @@ -40,27 +36,33 @@ public abstract class ClassBuilder { return v; } } - public FieldVisitor newField(@Nullable PsiElement origin, - int access, - String name, - String desc, - @Nullable String signature, - @Nullable Object value) { + + public FieldVisitor newField( + @Nullable PsiElement origin, + int access, + String name, + String desc, + @Nullable String signature, + @Nullable Object value + ) { return getVisitor().visitField(access, name, desc, signature, value); } - public MethodVisitor newMethod(@Nullable PsiElement origin, - int access, - String name, - String desc, - @Nullable String signature, - @Nullable String[] exceptions) { + public MethodVisitor newMethod( + @Nullable PsiElement origin, + int access, + String name, + String desc, + @Nullable String signature, + @Nullable String[] exceptions + ) { return getVisitor().visitMethod(access, name, desc, signature, exceptions); } - - public AnnotationVisitor newAnnotation(PsiElement origin, - String desc, - boolean visible) { + + public AnnotationVisitor newAnnotation( + String desc, + boolean visible + ) { return getVisitor().visitAnnotation(desc, visible); } @@ -70,7 +72,15 @@ public abstract class ClassBuilder { public abstract ClassVisitor getVisitor(); - public void defineClass(PsiElement origin, int version, int access, String name, @Nullable String signature, String superName, String[] interfaces) { + public void defineClass( + PsiElement origin, + int version, + int access, + String name, + @Nullable String signature, + String superName, + String[] interfaces + ) { getVisitor().visit(version, access & ~Opcodes.ACC_STATIC, name, signature, superName, interfaces); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderFactories.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderFactories.java index 9345f38177d..1bc6620a805 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderFactories.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderFactories.java @@ -17,7 +17,6 @@ package org.jetbrains.jet.codegen; import org.jetbrains.annotations.NotNull; -import org.jetbrains.asm4.ClassVisitor; import org.jetbrains.asm4.ClassWriter; import org.jetbrains.asm4.util.TraceClassVisitor; @@ -27,6 +26,7 @@ import java.io.StringWriter; /** * @author Stepan Koltsov */ +@SuppressWarnings("IOResourceOpenedButNotSafelyClosed") public class ClassBuilderFactories { public static ClassBuilderFactory TEST = new ClassBuilderFactory() { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderFactory.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderFactory.java index bcc95a0a8ec..5634086919c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderFactory.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderFactory.java @@ -17,11 +17,6 @@ package org.jetbrains.jet.codegen; import org.jetbrains.annotations.NotNull; -import org.jetbrains.asm4.ClassWriter; -import org.jetbrains.asm4.util.TraceClassVisitor; - -import java.io.PrintWriter; -import java.io.StringWriter; /** * @author max @@ -29,7 +24,10 @@ import java.io.StringWriter; public interface ClassBuilderFactory { @NotNull ClassBuilderMode getClassBuilderMode(); + ClassBuilder newClassBuilder(); + String asText(ClassBuilder builder); + byte[] asBytes(ClassBuilder builder); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderMode.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderMode.java index 096391c2be8..c68def746aa 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderMode.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderMode.java @@ -17,13 +17,19 @@ package org.jetbrains.jet.codegen; /** -* @author Stepan Koltsov -*/ + * @author Stepan Koltsov + */ public enum ClassBuilderMode { - /** Full function bodies */ + /** + * Full function bodies + */ FULL, - /** Only function signatures */ + /** + * Only function signatures + */ SIGNATURES, - /** Function with stub bodies: just throw exception */ + /** + * Function with stub bodies: just throw exception + */ STUBS, } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java index acd8e708d86..be10b76e8fa 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java @@ -17,7 +17,6 @@ package org.jetbrains.jet.codegen; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -import org.jetbrains.jet.lang.descriptors.ClassKind; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java index b0226da2533..dbd73749039 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java @@ -18,9 +18,8 @@ package org.jetbrains.jet.codegen; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.JetFile; -import org.jetbrains.jet.lang.psi.JetPsiUtil; -import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.java.JvmClassName; +import org.jetbrains.jet.lang.resolve.name.FqName; import javax.inject.Inject; import java.util.*; @@ -49,7 +48,6 @@ public class ClassFileFactory { } - ClassBuilder newVisitor(String filePath) { state.getProgress().log("Emitting: " + filePath); final ClassBuilder answer = builderFactory.newClassBuilder(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java index 11dbb103f1e..ae1008d0445 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java @@ -23,6 +23,12 @@ package org.jetbrains.jet.codegen; import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Label; +import org.jetbrains.asm4.MethodVisitor; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; +import org.jetbrains.asm4.commons.Method; +import org.jetbrains.asm4.signature.SignatureWriter; import org.jetbrains.jet.codegen.signature.BothSignatureWriter; import org.jetbrains.jet.codegen.signature.JvmMethodParameterKind; import org.jetbrains.jet.codegen.signature.JvmMethodSignature; @@ -36,13 +42,6 @@ import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.lang.types.lang.JetStandardClasses; -import org.jetbrains.asm4.Label; -import org.jetbrains.asm4.MethodVisitor; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; -import org.jetbrains.asm4.commons.Method; -import org.jetbrains.asm4.signature.SignatureWriter; import java.util.ArrayList; import java.util.List; @@ -59,26 +58,26 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { } public static JvmMethodSignature erasedInvokeSignature(FunctionDescriptor fd) { - + BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, false); - + signatureWriter.writeFormalTypeParametersStart(); signatureWriter.writeFormalTypeParametersEnd(); - + boolean isExtensionFunction = fd.getReceiverParameter().exists(); int paramCount = fd.getValueParameters().size(); if (isExtensionFunction) { paramCount++; } - + signatureWriter.writeParametersStart(); - + for (int i = 0; i < paramCount; ++i) { signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE); signatureWriter.writeAsmType(JetTypeMapper.TYPE_OBJECT, true); signatureWriter.writeParameterTypeEnd(); } - + signatureWriter.writeParametersEnd(); signatureWriter.writeReturnType(); @@ -98,10 +97,9 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { else { receiverParameterType = null; } - final CallableMethod result = new CallableMethod( + return new CallableMethod( owner, null, null, descriptor, INVOKEVIRTUAL, getInternalClassName(fd), receiverParameterType, getInternalClassName(fd).getAsmType()); - return result; } public JvmMethodSignature invokeSignature(FunctionDescriptor fd) { @@ -118,6 +116,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { SignatureWriter signatureWriter = new SignatureWriter(); + assert funDescriptor != null; final List parameters = funDescriptor.getValueParameters(); final JvmClassName funClass = getInternalClassName(funDescriptor); signatureWriter.visitClassType(funClass.getInternalName()); @@ -142,9 +141,12 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { generateBridge(name.getInternalName(), funDescriptor, fun, cv); captureThis = generateBody(funDescriptor, cv, (JetDeclarationWithBody) fun); ClassDescriptor thisDescriptor = context.getThisDescriptor(); - final Type enclosingType = thisDescriptor == null ? null : state.getInjector().getJetTypeMapper().mapType(thisDescriptor.getDefaultType(), MapTypeMode.VALUE); - if (enclosingType == null) + final Type enclosingType = thisDescriptor == null + ? null + : state.getInjector().getJetTypeMapper().mapType(thisDescriptor.getDefaultType(), MapTypeMode.VALUE); + if (enclosingType == null) { captureThis = null; + } final Method constructor = generateConstructor(funClass, fun, funDescriptor); @@ -158,16 +160,14 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { cv.done(); - final GeneratedAnonymousClassDescriptor answer = new GeneratedAnonymousClassDescriptor(name, constructor, captureThis, captureReceiver); + final GeneratedAnonymousClassDescriptor answer = + new GeneratedAnonymousClassDescriptor(name, constructor, captureThis, captureReceiver); for (DeclarationDescriptor descriptor : closure.keySet()) { if (descriptor == funDescriptor) { continue; } - if (descriptor instanceof VariableDescriptor) { - final EnclosedValueDescriptor valueDescriptor = closure.get(descriptor); - answer.addArg(valueDescriptor.getOuterValue()); - } - else if (CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) { + if (descriptor instanceof VariableDescriptor || CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && + descriptor.getContainingDeclaration() instanceof FunctionDescriptor) { final EnclosedValueDescriptor valueDescriptor = closure.get(descriptor); answer.addArg(valueDescriptor.getOuterValue()); } @@ -204,7 +204,8 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { } private Type generateBody(FunctionDescriptor funDescriptor, ClassBuilder cv, JetDeclarationWithBody body) { - ClassDescriptor function = state.getInjector().getJetTypeMapper().getClosureAnnotator().classDescriptorForFunctionDescriptor(funDescriptor, name); + ClassDescriptor function = + state.getInjector().getJetTypeMapper().getClosureAnnotator().classDescriptorForFunctionDescriptor(funDescriptor, name); final CodegenContexts.ClosureContext closureContext = context.intoClosure( funDescriptor, function, name, this, state.getInjector().getJetTypeMapper()); @@ -218,10 +219,13 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { final JvmMethodSignature bridge = erasedInvokeSignature(funDescriptor); final Method delegate = invokeSignature(funDescriptor).getAsmMethod(); - if (bridge.getAsmMethod().getDescriptor().equals(delegate.getDescriptor())) + if (bridge.getAsmMethod().getDescriptor().equals(delegate.getDescriptor())) { return; + } - final MethodVisitor mv = cv.newMethod(fun, ACC_PUBLIC | ACC_BRIDGE | ACC_VOLATILE, "invoke", bridge.getAsmMethod().getDescriptor(), null, new String[0]); + final MethodVisitor mv = + cv.newMethod(fun, ACC_PUBLIC | ACC_BRIDGE | ACC_VOLATILE, "invoke", bridge.getAsmMethod().getDescriptor(), null, + new String[0]); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { StubCodegen.generateStubCode(mv); } @@ -236,14 +240,16 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { int count = 1; if (receiver.exists()) { StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv); - StackValue.onStack(JetTypeMapper.TYPE_OBJECT).upcast(state.getInjector().getJetTypeMapper().mapType(receiver.getType(), MapTypeMode.VALUE), iv); + StackValue.onStack(JetTypeMapper.TYPE_OBJECT) + .upcast(state.getInjector().getJetTypeMapper().mapType(receiver.getType(), MapTypeMode.VALUE), iv); count++; } final List params = funDescriptor.getValueParameters(); for (ValueParameterDescriptor param : params) { StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv); - StackValue.onStack(JetTypeMapper.TYPE_OBJECT).upcast(state.getInjector().getJetTypeMapper().mapType(param.getType(), MapTypeMode.VALUE), iv); + StackValue.onStack(JetTypeMapper.TYPE_OBJECT) + .upcast(state.getInjector().getJetTypeMapper().mapType(param.getType(), MapTypeMode.VALUE), iv); count++; } @@ -261,7 +267,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { argCount += (captureReceiver != null ? 1 : 0); ArrayList variableDescriptors = new ArrayList(); - + for (DeclarationDescriptor descriptor : closure.keySet()) { if (descriptor == funDescriptor) { continue; @@ -270,7 +276,8 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { argCount++; variableDescriptors.add(descriptor); } - else if (CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) { + else if (CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && + descriptor.getContainingDeclaration() instanceof FunctionDescriptor) { argCount++; variableDescriptors.add(descriptor); } @@ -308,8 +315,11 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { } argTypes[i++] = type; } - else if (CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) { - final Type type = state.getInjector().getJetTypeMapper().getClosureAnnotator().classNameForAnonymousClass((JetElement) BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor)).getAsmType(); + else if (CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && + descriptor.getContainingDeclaration() instanceof FunctionDescriptor) { + final Type type = state.getInjector().getJetTypeMapper().getClosureAnnotator() + .classNameForAnonymousClass((JetElement) BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor)) + .getAsmType(); argTypes[i++] = type; } } @@ -374,16 +384,6 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { } } - public static ClassDescriptor getInternalType(FunctionDescriptor descriptor) { - final int paramCount = descriptor.getValueParameters().size(); - if (descriptor.getReceiverParameter().exists()) { - return JetStandardClasses.getReceiverFunction(paramCount); - } - else { - return JetStandardClasses.getFunction(paramCount); - } - } - private void appendType(SignatureWriter signatureWriter, JetType type, char variance) { signatureWriter.visitTypeArgument(variance); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java index 382fa0221fe..fb2f2b1b710 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java @@ -18,14 +18,14 @@ package org.jetbrains.jet.codegen; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.resolve.java.JvmClassName; -import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; -import java.util.*; +import java.util.Collections; +import java.util.HashMap; /* * @author max @@ -39,26 +39,32 @@ public abstract class CodegenContext { private final OwnerKind contextKind; @Nullable private final CodegenContext parentContext; - public final ObjectOrClosureCodegen closure; + public final ObjectOrClosureCodegen closure; HashMap accessors; protected StackValue outerExpression; - protected Type outerWasUsed ; + protected Type outerWasUsed; - public CodegenContext(@NotNull DeclarationDescriptor contextDescriptor, OwnerKind contextKind, @Nullable CodegenContext parentContext, @Nullable ObjectOrClosureCodegen closureCodegen) { + public CodegenContext( + @NotNull DeclarationDescriptor contextDescriptor, + OwnerKind contextKind, + @Nullable CodegenContext parentContext, + @Nullable ObjectOrClosureCodegen closureCodegen + ) { this.contextDescriptor = contextDescriptor; this.contextKind = contextKind; this.parentContext = parentContext; closure = closureCodegen; } - protected abstract ClassDescriptor getThisDescriptor (); + protected abstract ClassDescriptor getThisDescriptor(); public DeclarationDescriptor getClassOrNamespaceDescriptor() { CodegenContext c = this; - while(true) { + while (true) { + assert c != null; DeclarationDescriptor contextDescriptor = c.getContextDescriptor(); if (!(contextDescriptor instanceof ClassDescriptor) && !(contextDescriptor instanceof NamespaceDescriptor)) { c = c.getParentContext(); @@ -82,6 +88,7 @@ public abstract class CodegenContext { return prefix != null ? StackValue.composed(prefix, outerExpression) : outerExpression; } + @NotNull public DeclarationDescriptor getContextDescriptor() { return contextDescriptor; } @@ -95,14 +102,19 @@ public abstract class CodegenContext { } public CodegenContext intoNamespacePart(String delegateTo, NamespaceDescriptor descriptor) { - return new CodegenContexts.NamespaceContext(descriptor, this, new OwnerKind.StaticDelegateKind(StackValue.none(), delegateTo)); + return new CodegenContexts.NamespaceContext(descriptor, this, new OwnerKind.StaticDelegateKind(delegateTo)); } public CodegenContext intoClass(ClassDescriptor descriptor, OwnerKind kind, JetTypeMapper typeMapper) { return new CodegenContexts.ClassContext(descriptor, kind, this, typeMapper); } - public CodegenContext intoAnonymousClass(@NotNull ObjectOrClosureCodegen closure, ClassDescriptor descriptor, OwnerKind kind, JetTypeMapper typeMapper) { + public CodegenContext intoAnonymousClass( + @NotNull ObjectOrClosureCodegen closure, + ClassDescriptor descriptor, + OwnerKind kind, + JetTypeMapper typeMapper + ) { return new CodegenContexts.AnonymousClassContext(descriptor, kind, this, closure, typeMapper); } @@ -113,7 +125,8 @@ public abstract class CodegenContext { public CodegenContexts.ConstructorContext intoConstructor(ConstructorDescriptor descriptor, JetTypeMapper typeMapper) { if (descriptor == null) { descriptor = new ConstructorDescriptorImpl(getThisDescriptor(), Collections.emptyList(), true) - .initialize(Collections.emptyList(), Collections.emptyList(), Visibilities.PUBLIC); + .initialize(Collections.emptyList(), Collections.emptyList(), + Visibilities.PUBLIC); } return new CodegenContexts.ConstructorContext(descriptor, getContextKind(), this, typeMapper); } @@ -122,7 +135,13 @@ public abstract class CodegenContext { return new CodegenContexts.ScriptContext(script, classDescriptor, OwnerKind.IMPLEMENTATION, this, closure); } - public CodegenContexts.ClosureContext intoClosure(FunctionDescriptor funDescriptor, ClassDescriptor classDescriptor, JvmClassName internalClassName, ClosureCodegen closureCodegen, JetTypeMapper typeMapper) { + public CodegenContexts.ClosureContext intoClosure( + FunctionDescriptor funDescriptor, + ClassDescriptor classDescriptor, + JvmClassName internalClassName, + ClosureCodegen closureCodegen, + JetTypeMapper typeMapper + ) { return new CodegenContexts.ClosureContext(funDescriptor, classDescriptor, this, closureCodegen, internalClassName, typeMapper); } @@ -151,7 +170,9 @@ public abstract class CodegenContext { final ObjectOrClosureCodegen top = closure; if (top != null) { final StackValue answer = top.lookupInContext(d, result); - if (answer != null) { return result == null ? answer : StackValue.composed(result, answer); } + if (answer != null) { + return result == null ? answer : StackValue.composed(result, answer); + } StackValue outer = getOuterExpression(null); result = result == null ? outer : StackValue.composed(result, outer); @@ -171,17 +192,19 @@ public abstract class CodegenContext { DeclarationDescriptor getAccessor(DeclarationDescriptor descriptor) { if (accessors == null) { - accessors = new HashMap(); + accessors = new HashMap(); } descriptor = descriptor.getOriginal(); DeclarationDescriptor accessor = accessors.get(descriptor); - if (accessor != null) { return accessor; } + if (accessor != null) { + return accessor; + } if (descriptor instanceof SimpleFunctionDescriptor) { accessor = new AccessorForFunctionDescriptor(descriptor, contextDescriptor, accessors.size()); } else if (descriptor instanceof PropertyDescriptor) { - accessor = new AccessorForPropertyDescriptor((PropertyDescriptor) descriptor, contextDescriptor,accessors.size()); + accessor = new AccessorForPropertyDescriptor((PropertyDescriptor) descriptor, contextDescriptor, accessors.size()); } else { throw new UnsupportedOperationException(); @@ -201,7 +224,7 @@ public abstract class CodegenContext { public void copyAccessors(HashMap accessors) { if (accessors != null) { if (this.accessors == null) { - this.accessors = new HashMap(); + this.accessors = new HashMap(); } this.accessors.putAll(accessors); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContexts.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContexts.java index ace432563b9..6b8a997226b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContexts.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContexts.java @@ -18,21 +18,13 @@ package org.jetbrains.jet.codegen; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.descriptors.CallableDescriptor; -import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor; -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorVisitor; -import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; -import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; -import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor; -import org.jetbrains.jet.lang.descriptors.ScriptDescriptor; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; +import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.TypeSubstitutor; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -76,8 +68,10 @@ public class CodegenContexts { throw new IllegalStateException(); } - @NotNull @Override public Name getName() { - return null; + @NotNull + @Override + public Name getName() { + throw new IllegalStateException(); } } @@ -97,13 +91,17 @@ public class CodegenContexts { return "ROOT"; } }; - protected static final StackValue local0 = StackValue.local(0, JetTypeMapper.TYPE_OBJECT); protected static final StackValue local1 = StackValue.local(1, JetTypeMapper.TYPE_OBJECT); public abstract static class ReceiverContext extends CodegenContext { final CallableDescriptor receiverDescriptor; - public ReceiverContext(CallableDescriptor contextDescriptor, OwnerKind contextKind, CodegenContext parentContext, @Nullable ObjectOrClosureCodegen closureCodegen) { + public ReceiverContext( + CallableDescriptor contextDescriptor, + OwnerKind contextKind, + CodegenContext parentContext, + @Nullable ObjectOrClosureCodegen closureCodegen + ) { super(contextDescriptor, contextKind, parentContext, closureCodegen); receiverDescriptor = contextDescriptor.getReceiverParameter().exists() ? contextDescriptor : null; } @@ -114,39 +112,41 @@ public class CodegenContexts { } } - public static class MethodContext extends ReceiverContext { - @NotNull - private final FunctionDescriptor functionDescriptor; + public static class MethodContext extends ReceiverContext { public MethodContext(@NotNull FunctionDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext) { - super(contextType instanceof PropertyAccessorDescriptor ? ((PropertyAccessorDescriptor)contextType).getCorrespondingProperty() : contextType, contextKind, parentContext, null); - this.functionDescriptor = contextType; - } - - @NotNull - public FunctionDescriptor getFunctionDescriptor() { - return functionDescriptor; + super(contextType instanceof PropertyAccessorDescriptor + ? ((PropertyAccessorDescriptor) contextType).getCorrespondingProperty() + : contextType, contextKind, parentContext, null); } @Override protected ClassDescriptor getThisDescriptor() { + //noinspection ConstantConditions return getParentContext().getThisDescriptor(); } + @Override public StackValue lookupInContext(DeclarationDescriptor d, InstructionAdapter v, StackValue result) { + //noinspection ConstantConditions return getParentContext().lookupInContext(d, v, result); } + @Override public Type enclosingClassType(JetTypeMapper typeMapper) { + //noinspection ConstantConditions return getParentContext().enclosingClassType(typeMapper); } @Override public boolean isStatic() { + //noinspection ConstantConditions return getParentContext().isStatic(); } + @Override protected StackValue getOuterExpression(StackValue prefix) { + //noinspection ConstantConditions return getParentContext().getOuterExpression(prefix); } @@ -157,15 +157,21 @@ public class CodegenContexts { } public static class ConstructorContext extends MethodContext { - public ConstructorContext(ConstructorDescriptor contextDescriptor, OwnerKind kind, CodegenContext parent, JetTypeMapper typeMapper) { + public ConstructorContext( + ConstructorDescriptor contextDescriptor, + OwnerKind kind, + CodegenContext parent, + JetTypeMapper typeMapper + ) { super(contextDescriptor, kind, parent); final Type type = enclosingClassType(typeMapper); outerExpression = type != null - ? local1 - : null; + ? local1 + : null; } + @Override protected StackValue getOuterExpression(StackValue prefix) { return outerExpression; } @@ -188,7 +194,8 @@ public class CodegenContexts { @NotNull ClassDescriptor contextDescriptor, @NotNull OwnerKind contextKind, @Nullable CodegenContext parentContext, - @Nullable ObjectOrClosureCodegen closureCodegen) { + @Nullable ObjectOrClosureCodegen closureCodegen + ) { super(contextDescriptor, contextKind, parentContext, closureCodegen); this.classDescriptor = contextDescriptor; @@ -212,13 +219,18 @@ public class CodegenContexts { } public static class ClassContext extends CodegenContext { - public ClassContext(ClassDescriptor contextDescriptor, OwnerKind contextKind, CodegenContext parentContext, JetTypeMapper typeMapper) { + public ClassContext( + ClassDescriptor contextDescriptor, + OwnerKind contextKind, + CodegenContext parentContext, + JetTypeMapper typeMapper + ) { super(contextDescriptor, contextKind, parentContext, null); final Type type = enclosingClassType(typeMapper); outerExpression = type != null - ? StackValue.field(type, typeMapper.getJvmClassName(contextDescriptor), "this$0", false) - : null; + ? StackValue.field(type, typeMapper.getJvmClassName(contextDescriptor), "this$0", false) + : null; } @Override @@ -233,14 +245,20 @@ public class CodegenContexts { } public static class AnonymousClassContext extends CodegenContext { - public AnonymousClassContext(ClassDescriptor contextDescriptor, OwnerKind contextKind, CodegenContext parentContext, @NotNull ObjectOrClosureCodegen closure, JetTypeMapper typeMapper) { + public AnonymousClassContext( + ClassDescriptor contextDescriptor, + OwnerKind contextKind, + CodegenContext parentContext, + @NotNull ObjectOrClosureCodegen closure, + JetTypeMapper typeMapper + ) { super(contextDescriptor, contextKind, parentContext, closure); final Type type = enclosingClassType(typeMapper); Type owner = closure.state.getInjector().getJetTypeMapper().mapType(contextDescriptor.getDefaultType(), MapTypeMode.IMPL); outerExpression = type != null - ? StackValue.field(type, JvmClassName.byType(owner), "this$0", false) - : null; + ? StackValue.field(type, JvmClassName.byType(owner), "this$0", false) + : null; } @Override @@ -260,16 +278,23 @@ public class CodegenContexts { } public static class ClosureContext extends ReceiverContext { - private ClassDescriptor classDescriptor; + private final ClassDescriptor classDescriptor; - public ClosureContext(FunctionDescriptor contextDescriptor, ClassDescriptor classDescriptor, CodegenContext parentContext, @NotNull ObjectOrClosureCodegen closureCodegen, JvmClassName internalClassName, JetTypeMapper typeMapper) { + public ClosureContext( + FunctionDescriptor contextDescriptor, + ClassDescriptor classDescriptor, + CodegenContext parentContext, + @NotNull ObjectOrClosureCodegen closureCodegen, + JvmClassName internalClassName, + JetTypeMapper typeMapper + ) { super(contextDescriptor, OwnerKind.IMPLEMENTATION, parentContext, closureCodegen); this.classDescriptor = classDescriptor; final Type type = enclosingClassType(typeMapper); outerExpression = type != null - ? StackValue.field(type, internalClassName, "this$0", false) - : null; + ? StackValue.field(type, internalClassName, "this$0", false) + : null; } @Override @@ -277,6 +302,7 @@ public class CodegenContexts { return classDescriptor; } + @NotNull @Override public DeclarationDescriptor getContextDescriptor() { return classDescriptor; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java index cb7078f5321..2b8b0f84199 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java @@ -25,12 +25,12 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.lang.resolve.name.Name; -import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import java.util.BitSet; -import java.util.Collections; import java.util.Collection; +import java.util.Collections; import java.util.Random; /** @@ -64,20 +64,20 @@ public class CodegenUtil { CallableMemberDescriptor.Kind.DECLARATION); invokeDescriptor.initialize(fd.getReceiverParameter().exists() ? fd.getReceiverParameter().getType() : null, - fd.getExpectedThisObject(), - Collections.emptyList(), - fd.getValueParameters(), - fd.getReturnType(), - Modality.FINAL, - Visibilities.PUBLIC, - /*isInline = */false + fd.getExpectedThisObject(), + Collections.emptyList(), + fd.getValueParameters(), + fd.getReturnType(), + Modality.FINAL, + Visibilities.PUBLIC, + /*isInline = */false ); return invokeDescriptor; } public static boolean isNonLiteralObject(JetClassOrObject myClass) { return myClass instanceof JetObjectDeclaration && !((JetObjectDeclaration) myClass).isObjectLiteral() && - !(myClass.getParent() instanceof JetClassObject); + !(myClass.getParent() instanceof JetClassObject); } public static boolean isLocalFun(DeclarationDescriptor fd, BindingContext bindingContext) { @@ -109,7 +109,9 @@ public class CodegenUtil { } - public static @NotNull BitSet getFlagsForVisibility(@NotNull Visibility visibility) { + public static + @NotNull + BitSet getFlagsForVisibility(@NotNull Visibility visibility) { BitSet flags = new BitSet(); if (visibility == Visibilities.INTERNAL) { flags.set(JvmStdlibNames.FLAG_INTERNAL_BIT); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CompilationErrorHandler.java b/compiler/backend/src/org/jetbrains/jet/codegen/CompilationErrorHandler.java index a3b2acf3846..678c890fac5 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CompilationErrorHandler.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CompilationErrorHandler.java @@ -25,7 +25,7 @@ public interface CompilationErrorHandler { @Override public void reportException(Throwable exception, String fileUrl) { if (exception instanceof RuntimeException) { - throw (RuntimeException)exception; + throw (RuntimeException) exception; } throw new IllegalStateException(exception); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CompilationException.java b/compiler/backend/src/org/jetbrains/jet/codegen/CompilationException.java index f5de01c32f2..f48a303a0f7 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CompilationException.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CompilationException.java @@ -24,9 +24,9 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; /** -* @author alex.tkachman -* @author abreslav -*/ + * @author alex.tkachman + * @author abreslav + */ public class CompilationException extends RuntimeException { private final PsiElement element; @@ -56,7 +56,8 @@ public class CompilationException extends RuntimeException { return ApplicationManager.getApplication().runReadAction(new Computable() { @Override public String compute() { - StringBuilder message = new StringBuilder("Back-end (JVM) Internal error: ").append(CompilationException.super.getMessage()).append("\n"); + StringBuilder message = + new StringBuilder("Back-end (JVM) Internal error: ").append(CompilationException.super.getMessage()).append("\n"); Throwable cause = getCause(); if (cause != null) { String causeMessage = cause.getMessage(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java b/compiler/backend/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java index 1bb7d916fde..8f15765b90f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java @@ -17,10 +17,10 @@ package org.jetbrains.jet.codegen; import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.Type; import org.jetbrains.jet.lang.descriptors.ClassKind; import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; -import org.jetbrains.asm4.Type; import java.util.Collections; import java.util.List; @@ -31,7 +31,6 @@ import java.util.List; */ public class ConstructorFrameMap extends FrameMap { private int myOuterThisIndex = -1; - private int myTypeInfoIndex = -1; public ConstructorFrameMap(CallableMethod callableMethod, @Nullable ConstructorDescriptor descriptor, boolean hasThis0) { enterTemp(); // this @@ -62,8 +61,4 @@ public class ConstructorFrameMap extends FrameMap { public int getOuterThisIndex() { return myOuterThisIndex; } - - public int getTypeInfoIndex() { - return myTypeInfoIndex; - } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index c86f9ceb7e4..8fcc3ecc98c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -24,6 +24,12 @@ import com.intellij.psi.PsiMethod; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.Label; +import org.jetbrains.asm4.MethodVisitor; +import org.jetbrains.asm4.Opcodes; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; +import org.jetbrains.asm4.commons.Method; import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod; import org.jetbrains.jet.codegen.signature.JvmPropertyAccessorSignature; import org.jetbrains.jet.lang.descriptors.*; @@ -40,12 +46,6 @@ import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.jetbrains.jet.lang.types.lang.JetStandardLibraryNames; import org.jetbrains.jet.lexer.JetTokens; -import org.jetbrains.asm4.Label; -import org.jetbrains.asm4.MethodVisitor; -import org.jetbrains.asm4.Opcodes; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; -import org.jetbrains.asm4.commons.Method; import java.util.*; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FrameMap.java b/compiler/backend/src/org/jetbrains/jet/codegen/FrameMap.java index 4405ca52129..f9e07cc51a8 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FrameMap.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FrameMap.java @@ -132,12 +132,15 @@ public class FrameMap { Collections.sort(descriptors, new Comparator>() { @Override - public int compare(Tuple3 left, Tuple3 right) { + public int compare( + Tuple3 left, + Tuple3 right + ) { return left._2 - right._2; } }); - sb.append("size=" + myMaxIndex); + sb.append("size=").append(myMaxIndex); boolean first = true; for (Tuple3 t : descriptors) { @@ -145,7 +148,7 @@ public class FrameMap { sb.append(", "); } first = false; - sb.append(t._1 + ",i=" + t._2 + ",s=" + t._3); + sb.append(t._1).append(",i=").append(t._2).append(",s=").append(t._3); } return sb.toString(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index a745a601f41..0a6023213d1 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -19,6 +19,11 @@ package org.jetbrains.jet.codegen; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.Label; +import org.jetbrains.asm4.MethodVisitor; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; +import org.jetbrains.asm4.commons.Method; import org.jetbrains.jet.codegen.signature.JvmMethodSignature; import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter; import org.jetbrains.jet.codegen.signature.kotlin.JetValueParameterAnnotationWriter; @@ -32,11 +37,6 @@ import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; -import org.jetbrains.asm4.Label; -import org.jetbrains.asm4.MethodVisitor; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; -import org.jetbrains.asm4.commons.Method; import java.util.*; @@ -61,13 +61,17 @@ public class FunctionCodegen { public void gen(JetNamedFunction f) { final SimpleFunctionDescriptor functionDescriptor = state.getBindingContext().get(BindingContext.FUNCTION, f); assert functionDescriptor != null; - JvmMethodSignature method = state.getInjector().getJetTypeMapper().mapToCallableMethod(functionDescriptor, false, owner.getContextKind()).getSignature(); + JvmMethodSignature method = + state.getInjector().getJetTypeMapper().mapToCallableMethod(functionDescriptor, false, owner.getContextKind()) + .getSignature(); generateMethod(f, method, true, null, functionDescriptor); } - public void generateMethod(JetDeclarationWithBody f, + public void generateMethod( + JetDeclarationWithBody f, JvmMethodSignature jvmMethod, boolean needJetAnnotations, - @Nullable String propertyTypeSignature, FunctionDescriptor functionDescriptor) { + @Nullable String propertyTypeSignature, FunctionDescriptor functionDescriptor + ) { CodegenContexts.MethodContext funContext = owner.intoFunction(functionDescriptor); @@ -75,40 +79,39 @@ public class FunctionCodegen { generatedMethod(bodyExpression, jvmMethod, needJetAnnotations, propertyTypeSignature, funContext, functionDescriptor, f); } - private void generatedMethod(JetExpression bodyExpressions, + private void generatedMethod( + JetExpression bodyExpressions, JvmMethodSignature jvmSignature, boolean needJetAnnotations, @Nullable String propertyTypeSignature, CodegenContexts.MethodContext context, FunctionDescriptor functionDescriptor, JetDeclarationWithBody fun - ) - { + ) { if (functionDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { throw new IllegalStateException("must not generate code for fake overrides"); } List paramDescrs = functionDescriptor.getValueParameters(); - List typeParameters = (functionDescriptor instanceof PropertyAccessorDescriptor ? ((PropertyAccessorDescriptor)functionDescriptor).getCorrespondingProperty(): functionDescriptor).getTypeParameters(); int flags = JetTypeMapper.getAccessModifiers(functionDescriptor, 0); - + if (!functionDescriptor.getValueParameters().isEmpty() - && functionDescriptor.getValueParameters().get(functionDescriptor.getValueParameters().size() - 1) - .getVarargElementType() != null) - { + && functionDescriptor.getValueParameters().get(functionDescriptor.getValueParameters().size() - 1) + .getVarargElementType() != null) { flags |= ACC_VARARGS; } Modality modality = functionDescriptor.getModality(); if (modality == Modality.FINAL) { DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration(); - if (!(containingDeclaration instanceof ClassDescriptor) || ((ClassDescriptor)containingDeclaration).getKind() != ClassKind.TRAIT) { + if (!(containingDeclaration instanceof ClassDescriptor) || + ((ClassDescriptor) containingDeclaration).getKind() != ClassKind.TRAIT) { flags |= ACC_FINAL; } } OwnerKind kind = context.getContextKind(); - + if (kind == OwnerKind.TRAIT_IMPL) { needJetAnnotations = false; } @@ -118,16 +121,19 @@ public class FunctionCodegen { if (kind != OwnerKind.TRAIT_IMPL || bodyExpressions != null) { boolean isStatic = kind == OwnerKind.NAMESPACE || kind instanceof OwnerKind.StaticDelegateKind; - if (isStatic || kind == OwnerKind.TRAIT_IMPL) + if (isStatic || kind == OwnerKind.TRAIT_IMPL) { flags |= ACC_STATIC; + } boolean isAbstract = ( - modality == Modality.ABSTRACT - || CodegenUtil.isInterface(functionDescriptor.getContainingDeclaration()) - ) && !isStatic && kind != OwnerKind.TRAIT_IMPL; + modality == Modality.ABSTRACT + || CodegenUtil.isInterface(functionDescriptor.getContainingDeclaration()) + ) && !isStatic && kind != OwnerKind.TRAIT_IMPL; if (isAbstract) flags |= ACC_ABSTRACT; - - final MethodVisitor mv = v.newMethod(fun, flags, jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor(), jvmSignature.getGenericsSignature(), null); + + final MethodVisitor mv = + v.newMethod(fun, flags, jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor(), + jvmSignature.getGenericsSignature(), null); AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(functionDescriptor); if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES) { int start = 0; @@ -169,7 +175,7 @@ public class FunctionCodegen { } av.visitEnd(); } - for(int i = 0; i != paramDescrs.size(); ++i) { + for (int i = 0; i != paramDescrs.size(); ++i) { ValueParameterDescriptor parameterDescriptor = paramDescrs.get(i); AnnotationCodegen.forParameter(i, mv, state.getInjector().getJetTypeMapper()).genAnnotations(parameterDescriptor); JetValueParameterAnnotationWriter av = JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i + start); @@ -191,29 +197,33 @@ public class FunctionCodegen { if (!isAbstract && state.getClassBuilderMode() == ClassBuilderMode.FULL) { mv.visitCode(); - + Label methodBegin = new Label(); mv.visitLabel(methodBegin); - + FrameMap frameMap = context.prepareFrame(state.getInjector().getJetTypeMapper()); - ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getAsmMethod().getReturnType(), context, state); + ExpressionCodegen codegen = + new ExpressionCodegen(mv, frameMap, jvmSignature.getAsmMethod().getReturnType(), context, state); Type[] argTypes = jvmSignature.getAsmMethod().getArgumentTypes(); int add = 0; - if (kind == OwnerKind.TRAIT_IMPL) + if (kind == OwnerKind.TRAIT_IMPL) { add++; + } - if (receiverParameter.exists()) + if (receiverParameter.exists()) { add++; + } for (int i = 0; i < paramDescrs.size(); i++) { ValueParameterDescriptor parameter = paramDescrs.get(i); - frameMap.enter(parameter, argTypes[i+add].getSize()); + frameMap.enter(parameter, argTypes[i + add].getSize()); } - if (!isStatic && (kind instanceof OwnerKind.DelegateKind) != (functionDescriptor.getKind() == FunctionDescriptor.Kind.DELEGATION)) { + if (!isStatic && + (kind instanceof OwnerKind.DelegateKind) != (functionDescriptor.getKind() == FunctionDescriptor.Kind.DELEGATION)) { throw new IllegalStateException("mismatching kind in " + functionDescriptor); } @@ -225,6 +235,7 @@ public class FunctionCodegen { for (int i = 0, k = 0; i < argTypes.length; i++) { Type argType = argTypes[i]; iv.load(k, argType); + //noinspection AssignmentToForLoopParameter k += argType.getSize(); } iv.invokestatic(dk.getOwnerClass(), jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor()); @@ -239,7 +250,8 @@ public class FunctionCodegen { Type argType = argTypes[i]; iv.load(i + 1, argType); } - iv.invokeinterface(dk.getOwnerClass(), jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor()); + iv.invokeinterface(dk.getOwnerClass(), jvmSignature.getAsmMethod().getName(), + jvmSignature.getAsmMethod().getDescriptor()); iv.areturn(jvmSignature.getAsmMethod().getReturnType()); } else { @@ -253,11 +265,13 @@ public class FunctionCodegen { mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, sharedVarType.getInternalName(), "", "()V"); mv.visitVarInsn(localVarType.getOpcode(ILOAD), index); - mv.visitFieldInsn(PUTFIELD, sharedVarType.getInternalName(), "ref", StackValue.refType(localVarType).getDescriptor()); + mv.visitFieldInsn(PUTFIELD, sharedVarType.getInternalName(), "ref", + StackValue.refType(localVarType).getDescriptor()); Label labelToDivideLocalVarForSharedVarVisibility = new Label(); mv.visitLabel(labelToDivideLocalVarForSharedVarVisibility); - mapLabelsToDivideLocalVarVisibilityForSharedVar.put(parameter.getName(), labelToDivideLocalVarForSharedVarVisibility); + mapLabelsToDivideLocalVarVisibilityForSharedVar + .put(parameter.getName(), labelToDivideLocalVarForSharedVarVisibility); mv.visitVarInsn(sharedVarType.getOpcode(ISTORE), index); } @@ -265,7 +279,7 @@ public class FunctionCodegen { codegen.returnExpression(bodyExpressions); } - + Label methodEnd = new Label(); mv.visitLabel(methodEnd); @@ -282,7 +296,8 @@ public class FunctionCodegen { // TODO: specify signature mv.visitLocalVariable("this", type.getDescriptor(), null, methodBegin, methodEnd, k++); } - else if (fun instanceof JetFunctionLiteralExpression || CodegenUtil.isLocalFun(functionDescriptor, state.getBindingContext())) { + else if (fun instanceof JetFunctionLiteralExpression || + CodegenUtil.isLocalFun(functionDescriptor, state.getBindingContext())) { Type type = state.getInjector().getJetTypeMapper().mapType( context.getThisDescriptor().getDefaultType(), MapTypeMode.VALUE); mv.visitLocalVariable("this", type.getDescriptor(), null, methodBegin, methodEnd, k++); @@ -310,7 +325,8 @@ public class FunctionCodegen { mv.visitLocalVariable(nameForSharedVar, sharedVarType.getDescriptor(), null, divideLabel, methodEnd, k); k += Math.max(type.getSize(), sharedVarType.getSize()); - } else { + } + else { mv.visitLocalVariable(parameter.getName().getName(), type.getDescriptor(), null, methodBegin, methodEnd, k); k += type.getSize(); } @@ -326,7 +342,7 @@ public class FunctionCodegen { generateDefaultIfNeeded(context, state, v, jvmSignature.getAsmMethod(), functionDescriptor, kind); } - public static void endVisit(MethodVisitor mv, String description, PsiElement method) { + public static void endVisit(MethodVisitor mv, @Nullable String description, @Nullable PsiElement method) { try { mv.visitMaxs(-1, -1); } @@ -335,18 +351,30 @@ public class FunctionCodegen { } catch (Throwable t) { throw new CompilationException( - "wrong code generated" + (description != null ? " for " + description : "") + t.getClass().getName() + " " + t.getMessage(), - t, method); + "wrong code generated" + + (description != null ? " for " + description : "") + + t.getClass().getName() + + " " + + t.getMessage(), + t, method); } mv.visitEnd(); } - static void generateBridgeIfNeeded(CodegenContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, FunctionDescriptor functionDescriptor, OwnerKind kind) { + static void generateBridgeIfNeeded( + CodegenContext owner, + GenerationState state, + ClassBuilder v, + Method jvmSignature, + FunctionDescriptor functionDescriptor, + OwnerKind kind + ) { if (kind == OwnerKind.TRAIT_IMPL) { return; } - Method method = state.getInjector().getJetTypeMapper().mapSignature(functionDescriptor.getName(), functionDescriptor).getAsmMethod(); + Method method = + state.getInjector().getJetTypeMapper().mapSignature(functionDescriptor.getName(), functionDescriptor).getAsmMethod(); Queue bfsQueue = new LinkedList(); Set visited = new HashSet(); @@ -365,7 +393,8 @@ public class FunctionCodegen { while (!bfsQueue.isEmpty()) { FunctionDescriptor descriptor = bfsQueue.poll(); if (descriptor.getKind() == CallableMemberDescriptor.Kind.DECLARATION) { - Method overridden = state.getInjector().getJetTypeMapper().mapSignature(descriptor.getName(), descriptor.getOriginal()).getAsmMethod(); + Method overridden = + state.getInjector().getJetTypeMapper().mapSignature(descriptor.getName(), descriptor.getOriginal()).getAsmMethod(); if (differentMethods(method, overridden)) { bridgesToGenerate.add(overridden); } @@ -386,7 +415,14 @@ public class FunctionCodegen { } } - static void generateDefaultIfNeeded(CodegenContexts.MethodContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, @Nullable FunctionDescriptor functionDescriptor, OwnerKind kind) { + static void generateDefaultIfNeeded( + CodegenContexts.MethodContext owner, + GenerationState state, + ClassBuilder v, + Method jvmSignature, + @Nullable FunctionDescriptor functionDescriptor, + OwnerKind kind + ) { DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration(); if (kind != OwnerKind.TRAIT_IMPL) { @@ -395,8 +431,9 @@ public class FunctionCodegen { PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), contextClass); if (psiElement instanceof JetClass) { JetClass element = (JetClass) psiElement; - if (element.isTrait()) + if (element.isTrait()) { return; + } } } } @@ -428,14 +465,19 @@ public class FunctionCodegen { ownerInternalName = NamespaceCodegen.getJVMClassNameForKotlinNs(DescriptorUtils.getFQName(contextClass).toSafe()); } else { - ownerInternalName = JvmClassName.byType(state.getInjector().getJetTypeMapper().mapType(((ClassDescriptor) contextClass).getDefaultType(), MapTypeMode.IMPL)); + ownerInternalName = JvmClassName.byType(state.getInjector().getJetTypeMapper() + .mapType(((ClassDescriptor) contextClass).getDefaultType(), + MapTypeMode.IMPL)); } - String descriptor = jvmSignature.getDescriptor().replace(")","I)"); + String descriptor = jvmSignature.getDescriptor().replace(")", "I)"); boolean isConstructor = "".equals(jvmSignature.getName()); - if (!isStatic && !isConstructor) + if (!isStatic && !isConstructor) { descriptor = descriptor.replace("(", "(" + ownerInternalName.getDescriptor()); - final MethodVisitor mv = v.newMethod(null, flags | (isConstructor ? 0 : ACC_STATIC), isConstructor ? "" : jvmSignature.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, descriptor, null, null); + } + final MethodVisitor mv = v.newMethod(null, flags | (isConstructor ? 0 : ACC_STATIC), + isConstructor ? "" : jvmSignature.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, + descriptor, null, null); InstructionAdapter iv = new InstructionAdapter(mv); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { StubCodegen.generateStubCode(mv); @@ -469,7 +511,7 @@ public class FunctionCodegen { List paramDescrs = functionDescriptor.getValueParameters(); for (int i = 0; i < paramDescrs.size(); i++) { int size = argTypes[i + (hasReceiver ? 1 : 0)].getSize(); - frameMap.enter(paramDescrs.get(i),size); + frameMap.enter(paramDescrs.get(i), size); var += size; } @@ -503,7 +545,8 @@ public class FunctionCodegen { Label loadArg = new Label(); iv.ifeq(loadArg); - JetParameter jetParameter = (JetParameter) BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), parameterDescriptor); + JetParameter jetParameter = + (JetParameter) BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), parameterDescriptor); assert jetParameter != null; codegen.gen(jetParameter.getDefaultValue(), t); @@ -522,10 +565,12 @@ public class FunctionCodegen { iv.invokeinterface(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor()); } else { - if (!isConstructor) + if (!isConstructor) { iv.invokevirtual(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor()); - else + } + else { iv.invokespecial(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor()); + } } } else { @@ -534,26 +579,38 @@ public class FunctionCodegen { iv.areturn(jvmSignature.getReturnType()); - endVisit(mv, "default method", BindingContextUtils.callableDescriptorToDeclaration(state.getBindingContext(), functionDescriptor)); + endVisit(mv, "default method", + BindingContextUtils.callableDescriptorToDeclaration(state.getBindingContext(), functionDescriptor)); mv.visitEnd(); } } } private static boolean differentMethods(Method method, Method overridden) { - if (!method.getReturnType().equals(overridden.getReturnType())) + if (!method.getReturnType().equals(overridden.getReturnType())) { return true; + } Type[] methodArgumentTypes = method.getArgumentTypes(); Type[] overriddenArgumentTypes = overridden.getArgumentTypes(); - if (methodArgumentTypes.length != overriddenArgumentTypes.length) + if (methodArgumentTypes.length != overriddenArgumentTypes.length) { return true; - for(int i = 0; i != methodArgumentTypes.length; ++i) - if (!methodArgumentTypes[i].equals(overriddenArgumentTypes[i])) + } + for (int i = 0; i != methodArgumentTypes.length; ++i) { + if (!methodArgumentTypes[i].equals(overriddenArgumentTypes[i])) { return true; + } + } return false; } - - private static void generateBridge(CodegenContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, FunctionDescriptor functionDescriptor, Method overridden) { + + private static void generateBridge( + CodegenContext owner, + GenerationState state, + ClassBuilder v, + Method jvmSignature, + FunctionDescriptor functionDescriptor, + Method overridden + ) { int flags = ACC_PUBLIC | ACC_BRIDGE; // TODO. final MethodVisitor mv = v.newMethod(null, flags, jvmSignature.getName(), overridden.getDescriptor(), null, null); @@ -584,21 +641,30 @@ public class FunctionCodegen { iv.invokevirtual(state.getInjector().getJetTypeMapper().mapType( ((ClassDescriptor) owner.getContextDescriptor()).getDefaultType(), MapTypeMode.VALUE).getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor()); - if (JetTypeMapper.isPrimitive(jvmSignature.getReturnType()) && !JetTypeMapper.isPrimitive(overridden.getReturnType())) + if (JetTypeMapper.isPrimitive(jvmSignature.getReturnType()) && !JetTypeMapper.isPrimitive(overridden.getReturnType())) { StackValue.valueOf(iv, jvmSignature.getReturnType()); - if (jvmSignature.getReturnType() == Type.VOID_TYPE) + } + if (jvmSignature.getReturnType() == Type.VOID_TYPE) { iv.aconst(null); + } iv.areturn(overridden.getReturnType()); - endVisit(mv, "bridge method", BindingContextUtils.callableDescriptorToDeclaration(state.getBindingContext(), functionDescriptor)); + endVisit(mv, "bridge method", + BindingContextUtils.callableDescriptorToDeclaration(state.getBindingContext(), functionDescriptor)); } } public void genDelegate(FunctionDescriptor functionDescriptor, CallableMemberDescriptor overriddenDescriptor, StackValue field) { - JvmMethodSignature jvmMethodSignature = state.getInjector().getJetTypeMapper().mapSignature(functionDescriptor.getName(), functionDescriptor); + JvmMethodSignature jvmMethodSignature = + state.getInjector().getJetTypeMapper().mapSignature(functionDescriptor.getName(), functionDescriptor); genDelegate(functionDescriptor, overriddenDescriptor, field, jvmMethodSignature); } - public void genDelegate(CallableMemberDescriptor functionDescriptor, CallableMemberDescriptor overriddenDescriptor, StackValue field, JvmMethodSignature jvmMethodSignature) { + public void genDelegate( + CallableMemberDescriptor functionDescriptor, + CallableMemberDescriptor overriddenDescriptor, + StackValue field, + JvmMethodSignature jvmMethodSignature + ) { Method method = jvmMethodSignature.getAsmMethod(); int flags = ACC_PUBLIC | ACC_SYNTHETIC; // TODO. @@ -629,11 +695,14 @@ public class FunctionCodegen { iv.load(0, JetTypeMapper.TYPE_OBJECT); field.put(field.type, iv); ClassDescriptor classDescriptor = (ClassDescriptor) overriddenDescriptor.getContainingDeclaration(); - String internalName = state.getInjector().getJetTypeMapper().mapType(classDescriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(); - if (classDescriptor.getKind() == ClassKind.TRAIT) + String internalName = + state.getInjector().getJetTypeMapper().mapType(classDescriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(); + if (classDescriptor.getKind() == ClassKind.TRAIT) { iv.invokeinterface(internalName, method.getName(), method.getDescriptor()); - else + } + else { iv.invokevirtual(internalName, method.getName(), method.getDescriptor()); + } iv.areturn(method.getReturnType()); endVisit(mv, "delegate method", BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), functionDescriptor)); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/GeneratedAnonymousClassDescriptor.java b/compiler/backend/src/org/jetbrains/jet/codegen/GeneratedAnonymousClassDescriptor.java index 9d97cf95fe5..128723b104a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/GeneratedAnonymousClassDescriptor.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/GeneratedAnonymousClassDescriptor.java @@ -19,19 +19,19 @@ */ package org.jetbrains.jet.codegen; -import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.Method; +import org.jetbrains.jet.lang.resolve.java.JvmClassName; import java.util.ArrayList; import java.util.List; public class GeneratedAnonymousClassDescriptor { private final JvmClassName classname; - private Method constructor; + private final Method constructor; private final Type captureThis; private final Type captureReceiver; - private List args = new ArrayList(); + private final List args = new ArrayList(); public GeneratedAnonymousClassDescriptor(JvmClassName classname, Method constructor, Type captureThis, Type captureReceiver) { this.classname = classname; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/GeneratedClassLoader.java b/compiler/backend/src/org/jetbrains/jet/codegen/GeneratedClassLoader.java index 5bb039572d8..af9b12388ca 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/GeneratedClassLoader.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/GeneratedClassLoader.java @@ -19,15 +19,11 @@ package org.jetbrains.jet.codegen; import org.jetbrains.annotations.NotNull; /** -* @author yole -*/ + * @author yole + */ public class GeneratedClassLoader extends ClassLoader { private ClassFileFactory state; - public GeneratedClassLoader(@NotNull ClassFileFactory state) { - this(state, GeneratedClassLoader.class.getClassLoader()); - } - public GeneratedClassLoader(@NotNull ClassFileFactory state, ClassLoader parentClassLoader) { super(parentClassLoader); this.state = state; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java index 72e89ad3ac1..cb6465292c9 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java @@ -62,8 +62,10 @@ public class GenerationState { this(builderFactory, Progress.DEAF, analyzeExhaust, files, BuiltinToJavaTypesMapping.ENABLED); } - public GenerationState(ClassBuilderFactory builderFactory, Progress progress, - @NotNull AnalyzeExhaust exhaust, @NotNull List files, @NotNull BuiltinToJavaTypesMapping builtinToJavaTypesMapping) { + public GenerationState( + ClassBuilderFactory builderFactory, Progress progress, + @NotNull AnalyzeExhaust exhaust, @NotNull List files, @NotNull BuiltinToJavaTypesMapping builtinToJavaTypesMapping + ) { this.progress = progress; this.analyzeExhaust = exhaust; this.files = files; @@ -90,6 +92,7 @@ public class GenerationState { return progress; } + @NotNull public InjectorForJvmCodegen getInjector() { return injector; } @@ -112,15 +115,17 @@ public class GenerationState { } public ClassBuilder forClassImplementation(ClassDescriptor aClass) { - return getFactory().newVisitor(getInjector().getJetTypeMapper().mapType(aClass.getDefaultType(), MapTypeMode.IMPL).getInternalName() + ".class"); + return getFactory().newVisitor( + getInjector().getJetTypeMapper().mapType(aClass.getDefaultType(), MapTypeMode.IMPL).getInternalName() + ".class"); } - public ClassBuilder forNamespacepart(String name, JetFile file) { + public ClassBuilder forNamespacepart(String name) { return getFactory().newVisitor(name + ".class"); } public ClassBuilder forTraitImplementation(ClassDescriptor aClass) { - return getFactory().newVisitor(getInjector().getJetTypeMapper().mapType(aClass.getDefaultType(), MapTypeMode.TRAIT_IMPL).getInternalName() + ".class"); + return getFactory().newVisitor( + getInjector().getJetTypeMapper().mapType(aClass.getDefaultType(), MapTypeMode.TRAIT_IMPL).getInternalName() + ".class"); } public Pair forAnonymousSubclass(JetExpression expression) { @@ -142,7 +147,9 @@ public class GenerationState { for (JetFile file : this.files) { if (file.isScript()) { String name = ScriptNameUtil.classNameForScript(file); - injector.getClosureAnnotator().registerClassNameForScript(file.getScript(), JvmClassName.byInternalName(name)); + JetScript script = file.getScript(); + assert script != null; + injector.getClosureAnnotator().registerClassNameForScript(script, JvmClassName.byInternalName(name)); } } @@ -165,7 +172,8 @@ public class GenerationState { @NotNull JetScript script, @NotNull JvmClassName className, @NotNull List> earlierScripts, - @NotNull CompilationErrorHandler errorHandler) { + @NotNull CompilationErrorHandler errorHandler + ) { injector.getScriptCodegen().registerEarlierScripts(earlierScripts); injector.getClosureAnnotator().registerClassNameForScript(script, className); @@ -191,14 +199,18 @@ public class GenerationState { closure.cv = nameAndVisitor.getSecond(); closure.name = nameAndVisitor.getFirst(); final CodegenContext objectContext = closure.context.intoAnonymousClass( - closure, analyzeExhaust.getBindingContext().get(BindingContext.CLASS, objectDeclaration), OwnerKind.IMPLEMENTATION, injector.getJetTypeMapper()); + closure, analyzeExhaust.getBindingContext().get(BindingContext.CLASS, objectDeclaration), OwnerKind.IMPLEMENTATION, + injector.getJetTypeMapper()); new ImplementationBodyCodegen(objectDeclaration, objectContext, nameAndVisitor.getSecond(), this).generate(); ConstructorDescriptor constructorDescriptor = analyzeExhaust.getBindingContext().get(BindingContext.CONSTRUCTOR, objectDeclaration); + assert constructorDescriptor != null; CallableMethod callableMethod = injector.getJetTypeMapper().mapToCallableMethod( - constructorDescriptor, OwnerKind.IMPLEMENTATION, injector.getJetTypeMapper().hasThis0(constructorDescriptor.getContainingDeclaration())); - return new GeneratedAnonymousClassDescriptor(nameAndVisitor.first, callableMethod.getSignature().getAsmMethod(), objectContext.outerWasUsed, null); + constructorDescriptor, OwnerKind.IMPLEMENTATION, + injector.getJetTypeMapper().hasThis0(constructorDescriptor.getContainingDeclaration())); + return new GeneratedAnonymousClassDescriptor(nameAndVisitor.first, callableMethod.getSignature().getAsmMethod(), + objectContext.outerWasUsed, null); } public String createText() { @@ -207,10 +219,10 @@ public class GenerationState { final ClassFileFactory factory = getFactory(); List files = factory.files(); for (String file : files) { -// if (!file.startsWith("kotlin/")) { - answer.append("@").append(file).append('\n'); - answer.append(factory.asText(file)); -// } + // if (!file.startsWith("kotlin/")) { + answer.append("@").append(file).append('\n'); + answer.append(factory.asText(file)); + // } } return answer.toString(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 7504e3542f6..ce9fc75dc0d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -21,6 +21,11 @@ import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.util.Pair; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.AnnotationVisitor; +import org.jetbrains.asm4.MethodVisitor; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; +import org.jetbrains.asm4.commons.Method; import org.jetbrains.jet.codegen.signature.*; import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter; import org.jetbrains.jet.codegen.signature.kotlin.JetValueParameterAnnotationWriter; @@ -38,16 +43,11 @@ import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.utils.BitSetUtils; -import org.jetbrains.asm4.AnnotationVisitor; -import org.jetbrains.asm4.MethodVisitor; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; -import org.jetbrains.asm4.commons.Method; import java.util.*; -import static org.jetbrains.jet.codegen.JetTypeMapper.TYPE_OBJECT; import static org.jetbrains.asm4.Opcodes.*; +import static org.jetbrains.jet.codegen.JetTypeMapper.TYPE_OBJECT; /** * @author max @@ -139,12 +139,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } access |= ACC_ENUM; } + List interfaces = signature.getInterfaces(); v.defineClass(myClass, V1_6, access, signature.getName(), signature.getJavaGenericSignature(), signature.getSuperclassName(), - signature.getInterfaces().toArray(new String[0]) + interfaces.toArray(new String[interfaces.size()]) ); v.visitSource(myClass.getContainingFile().getName(), null); @@ -185,7 +186,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { AnnotationCodegen.forClass(v.getVisitor(), typeMapper).genAnnotations(descriptor); if (signature.getKotlinGenericSignature() != null || descriptor.getVisibility() != Visibilities.PUBLIC) { - AnnotationVisitor annotationVisitor = v.newAnnotation(myClass, JvmStdlibNames.JET_CLASS.getDescriptor(), true); + AnnotationVisitor annotationVisitor = v.newAnnotation(JvmStdlibNames.JET_CLASS.getDescriptor(), true); annotationVisitor.visit(JvmStdlibNames.JET_CLASS_SIGNATURE, signature.getKotlinGenericSignature()); BitSet flags = CodegenUtil.getFlagsForVisibility(descriptor.getVisibility()); int flagsValue = BitSetUtils.toInt(flags); @@ -286,6 +287,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); if (!CodegenUtil.isInterface(superClassDescriptor)) { superClassType = superType; + assert superClassDescriptor != null; superClass = typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName(); superCall = specifier; } @@ -412,10 +414,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod(); MethodVisitor mv = v.newMethod(null, ACC_BRIDGE | ACC_SYNTHETIC | ACC_STATIC, method.getName(), method.getDescriptor(), null, null); + PropertyGetterDescriptor getter = ((PropertyDescriptor) entry.getValue()).getGetter(); + assert getter != null; PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature(), originalSignature.getJvmMethodSignature().getKotlinTypeParameter(), original, - ((PropertyDescriptor) entry.getValue()).getGetter().getVisibility()); + getter.getVisibility()); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { StubCodegen.generateStubCode(mv); } @@ -445,10 +449,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod(); MethodVisitor mv = v.newMethod(null, ACC_STATIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null); + PropertySetterDescriptor setter = ((PropertyDescriptor) entry.getValue()).getSetter(); + assert setter != null; PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature(), originalSignature2.getJvmMethodSignature().getKotlinTypeParameter(), original, - ((PropertyDescriptor) entry.getValue()).getSetter().getVisibility()); + setter.getVisibility()); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { StubCodegen.generateStubCode(mv); } @@ -506,6 +512,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { final JetClassObject classObject = getClassObject(); if (classObject != null) { final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration()); + assert descriptor1 != null; Type type = Type.getObjectType(typeMapper.mapType(descriptor1.getDefaultType(), MapTypeMode.VALUE).getInternalName()); v.newField(classObject, ACC_PUBLIC | ACC_STATIC, "$classobj", type.getDescriptor(), null, null); @@ -513,6 +520,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { @Override public void generate(InstructionAdapter v) { final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration()); + assert descriptor1 != null; String name = typeMapper.mapType(descriptor1.getDefaultType(), MapTypeMode.IMPL).getInternalName(); final Type classObjectType = Type.getObjectType(name); v.anew(classObjectType); @@ -649,7 +657,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression() .getConstructorReferenceExpression()); - if (declarationDescriptor instanceof ClassDescriptor) { + if (declarationDescriptor instanceof ClassDescriptorFromSource) { declarationDescriptor = ((ClassDescriptorFromSource) declarationDescriptor).getUnsubstitutedPrimaryConstructor(); } ConstructorDescriptor superConstructor = (ConstructorDescriptor) declarationDescriptor; @@ -795,7 +803,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { k += closure.captureReceiver.getSize(); } - int l = 0; for (DeclarationDescriptor varDescr : closure.closure.keySet()) { if (varDescr instanceof VariableDescriptor && !(varDescr instanceof PropertyDescriptor)) { Type sharedVarType = typeMapper.getSharedVarType(varDescr); @@ -807,7 +814,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { k += StackValue.refType(sharedVarType).getSize(); iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "$" + varDescr.getName(), sharedVarType.getDescriptor()); - l++; } } } @@ -874,7 +880,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } for (Pair needDelegates : getTraitImplementations(descriptor)) { - CallableMemberDescriptor callableDescriptor = needDelegates.first; if (needDelegates.second instanceof SimpleFunctionDescriptor) { generateDelegationToTraitImpl((FunctionDescriptor) needDelegates.second, (FunctionDescriptor) needDelegates.first); } @@ -938,7 +943,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { aw.writePropertyType(jvmSignature.getKotlinReturnType()); } else { - aw.writeNullableReturnType(fun.getReturnType().isNullable()); + JetType returnType = fun.getReturnType(); + assert returnType != null; + aw.writeNullableReturnType(returnType.isNullable()); aw.writeTypeParameters(jvmSignature.getKotlinTypeParameter()); aw.writeReturnType(jvmSignature.getKotlinReturnType()); } @@ -1019,6 +1026,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ((JetDelegatorToSuperCall) superCall) .getCalleeExpression() .getConstructorReferenceExpression()); + assert superConstructor != null; CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, typeMapper.hasThis0(superConstructor.getContainingDeclaration())); int nextVar = firstSuperArgument + 1; @@ -1101,6 +1109,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { final JetDelegatorToSuperCall superCall = (JetDelegatorToSuperCall) specifier; ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) bindingContext .get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression()); + assert constructorDescriptor != null; CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, OwnerKind.IMPLEMENTATION, typeMapper .hasThis0(constructorDescriptor.getContainingDeclaration())); codegen.invokeMethodWithArguments(method, superCall, StackValue.none()); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index b41adfb3fb7..b7cca4de60c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -20,6 +20,8 @@ import com.google.common.collect.Maps; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.Opcodes; +import org.jetbrains.asm4.Type; import org.jetbrains.jet.codegen.signature.BothSignatureWriter; import org.jetbrains.jet.codegen.signature.JvmMethodParameterKind; import org.jetbrains.jet.codegen.signature.JvmMethodSignature; @@ -42,12 +44,13 @@ import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; import org.jetbrains.jet.lang.types.lang.JetStandardLibraryNames; import org.jetbrains.jet.lang.types.lang.PrimitiveType; import org.jetbrains.jet.lang.types.ref.ClassName; -import org.jetbrains.asm4.Opcodes; -import org.jetbrains.asm4.Type; import javax.annotation.PostConstruct; import javax.inject.Inject; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; import static org.jetbrains.asm4.Opcodes.*; @@ -122,6 +125,7 @@ public class JetTypeMapper { @Nullable public Type get(@NotNull JetType type) { ClassifierDescriptor classifier = type.getConstructor().getDeclarationDescriptor(); + assert classifier != null; return asmTypes.get(new SpecialTypeKey(DescriptorUtils.getFQName(classifier), type.isNullable())); } @@ -435,6 +439,7 @@ public class JetTypeMapper { throw new IllegalStateException("TRAIT_IMPL is not possible for " + jetType); } else if (kind == MapTypeMode.IMPL) { + //noinspection ConstantConditions if (mapBuiltinsToJava) { // TODO: enable and fix tests //throw new IllegalStateException("must not map known type to IMPL when not compiling builtins: " + jetType); @@ -756,7 +761,9 @@ public class JetTypeMapper { } else { signatureVisitor.writeReturnType(); - mapReturnType(f.getReturnType(), signatureVisitor); + JetType returnType = f.getReturnType(); + assert returnType != null; + mapReturnType(returnType, signatureVisitor); signatureVisitor.writeReturnTypeEnd(); } return signatureVisitor.makeJvmMethodSignature(f.getName().getName()); @@ -847,7 +854,9 @@ public class JetTypeMapper { signatureWriter.writeParametersEnd(); signatureWriter.writeReturnType(); - mapReturnType(f.getReturnType(), signatureWriter); + JetType returnType = f.getReturnType(); + assert returnType != null; + mapReturnType(returnType, signatureWriter); signatureWriter.writeReturnTypeEnd(); return signatureWriter.makeJvmMethodSignature(name.getName()); @@ -868,7 +877,7 @@ public class JetTypeMapper { signatureWriter.writeParametersStart(); if (kind == OwnerKind.TRAIT_IMPL) { - ClassDescriptor containingDeclaration = (ClassDescriptor) parentDescriptor; + @SuppressWarnings("ConstantConditions") ClassDescriptor containingDeclaration = (ClassDescriptor) parentDescriptor; signatureWriter.writeParameterType(JvmMethodParameterKind.THIS); mapType(containingDeclaration.getDefaultType(), signatureWriter, MapTypeMode.IMPL); signatureWriter.writeParameterTypeEnd(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/MapTypeMode.java b/compiler/backend/src/org/jetbrains/jet/codegen/MapTypeMode.java index e29d76067ac..ab6652cecbf 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/MapTypeMode.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/MapTypeMode.java @@ -20,12 +20,20 @@ package org.jetbrains.jet.codegen; * @author Stepan Koltsov */ public enum MapTypeMode { - /** jet.Int is mapped to Ljet/Int; */ + /** + * jet.Int is mapped to Ljet/Int; + */ IMPL, - /** jet.Int is mapped to Ljet/Impl$TImpl; */ + /** + * jet.Int is mapped to Ljet/Impl$TImpl; + */ TRAIT_IMPL, - /** jet.Int is mapped to I */ + /** + * jet.Int is mapped to I + */ VALUE, - /** jet.Int is mapped to Ljava/lang/Integer; */ + /** + * jet.Int is mapped to Ljava/lang/Integer; + */ TYPE_PARAMETER, } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java index 8b2f88cb965..30faa2bcbf3 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java @@ -37,8 +37,10 @@ public class MemberCodegen { } - public void generateFunctionOrProperty(@NotNull JetTypeParameterListOwner functionOrProperty, - @NotNull CodegenContext context, @NotNull ClassBuilder classBuilder) { + public void generateFunctionOrProperty( + @NotNull JetTypeParameterListOwner functionOrProperty, + @NotNull CodegenContext context, @NotNull ClassBuilder classBuilder + ) { FunctionCodegen functionCodegen = new FunctionCodegen(context, classBuilder, state); if (functionOrProperty instanceof JetNamedFunction) { try { @@ -66,5 +68,4 @@ public class MemberCodegen { throw new IllegalArgumentException("Unknown parameter: " + functionOrProperty); } } - } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index da0314565b7..6349b106159 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -18,10 +18,12 @@ package org.jetbrains.jet.codegen; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.progress.ProcessCanceledException; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.MethodVisitor; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; @@ -32,11 +34,7 @@ import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.utils.Progress; -import org.jetbrains.asm4.MethodVisitor; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; -import java.util.ArrayList; import java.util.Collection; import static org.jetbrains.asm4.Opcodes.*; @@ -50,9 +48,13 @@ public class NamespaceCodegen { @NotNull private final FqName name; private final GenerationState state; private final Collection files; - private int nextMultiFile = 0; - public NamespaceCodegen(@NotNull ClassBuilderOnDemand v, @NotNull final FqName fqName, GenerationState state, Collection namespaceFiles) { + public NamespaceCodegen( + @NotNull ClassBuilderOnDemand v, + @NotNull final FqName fqName, + GenerationState state, + Collection namespaceFiles + ) { checkAllFilesHaveSameNamespace(namespaceFiles); this.v = v; @@ -77,7 +79,6 @@ public class NamespaceCodegen { v.visitSource(sourceFile.getName(), null); } }); - } public void generate(CompilationErrorHandler errorHandler, final Progress progress) { @@ -101,7 +102,7 @@ public class NamespaceCodegen { throw e; } catch (Throwable e) { - if(errorHandler != null) errorHandler.reportException(e, vFile == null ? "no file" : vFile.getUrl()); + if (errorHandler != null) errorHandler.reportException(e, vFile == null ? "no file" : vFile.getUrl()); DiagnosticUtils.throwIfRunningOnServer(e); if (ApplicationManager.getApplication().isInternal()) { e.printStackTrace(); @@ -151,17 +152,17 @@ public class NamespaceCodegen { if (k > 0) { PsiFile containingFile = file.getContainingFile(); String fname = containingFile.getName(); - fname = fname.substring(0,fname.lastIndexOf('.')); - String className = name.child(Name.identifier("namespace$src$" + fname)).getFqName().replace('.','/'); - ClassBuilder builder = state.forNamespacepart(className, file); + fname = fname.substring(0, fname.lastIndexOf('.')); + String className = name.child(Name.identifier("namespace$src$" + fname)).getFqName().replace('.', '/'); + ClassBuilder builder = state.forNamespacepart(className); builder.defineClass(containingFile, V1_6, - ACC_PUBLIC/*|ACC_SUPER*/, - className, - null, - //"jet/lang/Namespace", - "java/lang/Object", - new String[0] + ACC_PUBLIC/*|ACC_SUPER*/, + className, + null, + //"jet/lang/Namespace", + "java/lang/Object", + new String[0] ); builder.visitSource(containingFile.getName(), null); @@ -169,11 +170,13 @@ public class NamespaceCodegen { if (declaration instanceof JetNamedFunction) { { final CodegenContext context = CodegenContexts.STATIC.intoNamespace(descriptor); - state.getInjector().getMemberCodegen().generateFunctionOrProperty((JetTypeParameterListOwner) declaration, context, builder); + state.getInjector().getMemberCodegen() + .generateFunctionOrProperty((JetTypeParameterListOwner) declaration, context, builder); } { final CodegenContext context = CodegenContexts.STATIC.intoNamespacePart(className, descriptor); - state.getInjector().getMemberCodegen().generateFunctionOrProperty((JetTypeParameterListOwner) declaration, context, v.getClassBuilder()); + state.getInjector().getMemberCodegen() + .generateFunctionOrProperty((JetTypeParameterListOwner) declaration, context, v.getClassBuilder()); } } } @@ -234,7 +237,8 @@ public class NamespaceCodegen { if (declaration instanceof JetProperty) { final JetExpression initializer = ((JetProperty) declaration).getInitializer(); if (initializer != null && !(initializer instanceof JetConstantExpression)) { - final PropertyDescriptor descriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, declaration); + final PropertyDescriptor descriptor = + (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, declaration); assert descriptor != null; codegen.genToJVMStack(initializer); StackValue.Property propValue = codegen.intermediateValueForProperty(descriptor, true, null); @@ -260,7 +264,6 @@ public class NamespaceCodegen { if (initializer != null && !(initializer instanceof JetConstantExpression)) { return true; } - } } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ObjectOrClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ObjectOrClosureCodegen.java index 6eb31d83af5..16985a2ef7a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ObjectOrClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ObjectOrClosureCodegen.java @@ -17,13 +17,13 @@ package org.jetbrains.jet.codegen; import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.Opcodes; +import org.jetbrains.asm4.Type; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall; import org.jetbrains.jet.lang.psi.JetElement; import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.java.JvmClassName; -import org.jetbrains.asm4.Opcodes; -import org.jetbrains.asm4.Type; import java.util.LinkedHashMap; import java.util.Map; @@ -40,7 +40,8 @@ public class ObjectOrClosureCodegen { protected final CodegenContext context; protected ClassBuilder cv = null; public JvmClassName name = null; - protected Map closure = new LinkedHashMap(); + protected Map closure = + new LinkedHashMap(); public JetDelegatorToSuperCall superCall; public ObjectOrClosureCodegen(ExpressionCodegen exprContext, CodegenContext context, GenerationState state) { @@ -69,8 +70,8 @@ public class ObjectOrClosureCodegen { StackValue outerValue = StackValue.local(idx, type); final String fieldName = "$" + vd.getName(); StackValue innerValue = sharedVarType != null - ? StackValue.fieldForSharedVar(localType, name, fieldName) - : StackValue.field(type, name, fieldName, false); + ? StackValue.fieldForSharedVar(localType, name, fieldName) + : StackValue.field(type, name, fieldName, false); cv.newField(null, Opcodes.ACC_PUBLIC, fieldName, type.getDescriptor(), null, null); @@ -111,10 +112,12 @@ public class ObjectOrClosureCodegen { CodegenContexts.ReceiverContext fcontext = (CodegenContexts.ReceiverContext) context; - if (fcontext.getReceiverDescriptor() != fd) + if (fcontext.getReceiverDescriptor() != fd) { return null; + } - Type type = state.getInjector().getJetTypeMapper().mapType(fcontext.getReceiverDescriptor().getReceiverParameter().getType(), MapTypeMode.VALUE); + Type type = state.getInjector().getJetTypeMapper() + .mapType(fcontext.getReceiverDescriptor().getReceiverParameter().getType(), MapTypeMode.VALUE); boolean isStatic = fcontext.getContextDescriptor().getContainingDeclaration() instanceof NamespaceDescriptor; StackValue outerValue = StackValue.local(isStatic ? 0 : 1, type); final String fieldName = "receiver$0"; @@ -134,7 +137,7 @@ public class ObjectOrClosureCodegen { return null; } - public boolean isConst () { + public boolean isConst() { return captureThis == null && captureReceiver == null && closure.isEmpty(); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/OwnerKind.java b/compiler/backend/src/org/jetbrains/jet/codegen/OwnerKind.java index 85686c55086..000fe15c9fa 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/OwnerKind.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/OwnerKind.java @@ -50,19 +50,13 @@ public class OwnerKind { } public static class StaticDelegateKind extends OwnerKind { - private final StackValue delegate; private final String ownerClass; - public StaticDelegateKind(StackValue delegate, String ownerClass) { + public StaticDelegateKind(String ownerClass) { super("staticDelegateKind"); - this.delegate = delegate; this.ownerClass = ownerClass; } - public StackValue getDelegate() { - return delegate; - } - public String getOwnerClass() { return ownerClass; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ProjectionErasingJetType.java b/compiler/backend/src/org/jetbrains/jet/codegen/ProjectionErasingJetType.java deleted file mode 100644 index 74562cf0380..00000000000 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ProjectionErasingJetType.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2010-2012 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.jet.codegen; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; -import org.jetbrains.jet.lang.resolve.scopes.JetScope; -import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.lang.types.TypeConstructor; -import org.jetbrains.jet.lang.types.TypeProjection; -import org.jetbrains.jet.lang.types.Variance; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author alex.tkachman - * - * Utility class used by back-end to - */ -public class ProjectionErasingJetType implements JetType { - private final JetType delegate; - private List arguments; - - public ProjectionErasingJetType(JetType delegate) { - this.delegate = delegate; - arguments = new ArrayList(); - for(TypeProjection tp : delegate.getArguments()) { - arguments.add(new TypeProjection(Variance.INVARIANT, tp.getType())); - } - } - - @NotNull - @Override - public TypeConstructor getConstructor() { - return delegate.getConstructor(); - } - - @NotNull - @Override - public List getArguments() { - return arguments; - } - - @Override - public boolean isNullable() { - return false; - } - - @NotNull - @Override - public JetScope getMemberScope() { - return delegate.getMemberScope(); - } - - @Override - public List getAnnotations() { - return delegate.getAnnotations(); - } - - @Override - public int hashCode() { - return delegate.hashCode(); - } - - @Override - public boolean equals(Object obj) { - return ((obj instanceof ProjectionErasingJetType) && delegate.equals(((ProjectionErasingJetType)obj).delegate)) || delegate.equals(obj); - } -} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 2b43bb9085f..74e7957889c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -19,8 +19,13 @@ package org.jetbrains.jet.codegen; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter; +import org.jetbrains.asm4.FieldVisitor; +import org.jetbrains.asm4.MethodVisitor; +import org.jetbrains.asm4.Opcodes; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.signature.JvmPropertyAccessorSignature; +import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -31,11 +36,6 @@ import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; -import org.jetbrains.asm4.FieldVisitor; -import org.jetbrains.asm4.MethodVisitor; -import org.jetbrains.asm4.Opcodes; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.BitSet; @@ -62,9 +62,10 @@ public class PropertyCodegen { throw new UnsupportedOperationException("expect a property to have a property descriptor"); } final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; - if (kind == OwnerKind.NAMESPACE || kind == OwnerKind.IMPLEMENTATION || kind ==OwnerKind.TRAIT_IMPL ) { - if (kind != OwnerKind.TRAIT_IMPL) + if (kind == OwnerKind.NAMESPACE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.TRAIT_IMPL) { + if (kind != OwnerKind.TRAIT_IMPL) { generateBackingField(p, propertyDescriptor); + } generateGetter(p, propertyDescriptor); generateSetter(p, propertyDescriptor); } @@ -77,13 +78,15 @@ public class PropertyCodegen { } public void generateBackingField(PsiElement p, PropertyDescriptor propertyDescriptor) { + //noinspection ConstantConditions if (state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) { DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration(); - if (CodegenUtil.isInterface(containingDeclaration)) + if (CodegenUtil.isInterface(containingDeclaration)) { return; + } Object value = null; - final JetExpression initializer = p instanceof JetProperty ? ((JetProperty)p).getInitializer() : null; + final JetExpression initializer = p instanceof JetProperty ? ((JetProperty) p).getInitializer() : null; if (initializer != null) { if (initializer instanceof JetConstantExpression) { CompileTimeConstant compileTimeValue = state.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, initializer); @@ -113,8 +116,10 @@ public class PropertyCodegen { final JetPropertyAccessor getter = p.getGetter(); if (getter != null) { if (getter.getBodyExpression() != null) { - JvmPropertyAccessorSignature signature = state.getInjector().getJetTypeMapper().mapGetterSignature(propertyDescriptor, kind); - functionCodegen.generateMethod(getter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(), propertyDescriptor.getGetter()); + JvmPropertyAccessorSignature signature = + state.getInjector().getJetTypeMapper().mapGetterSignature(propertyDescriptor, kind); + functionCodegen.generateMethod(getter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(), + propertyDescriptor.getGetter()); } else if (isExternallyAccessible(propertyDescriptor)) { generateDefaultGetter(p); @@ -136,8 +141,11 @@ public class PropertyCodegen { if (setter.getBodyExpression() != null) { final PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter(); assert setterDescriptor != null; - JvmPropertyAccessorSignature signature = state.getInjector().getJetTypeMapper().mapSetterSignature(propertyDescriptor, kind); - functionCodegen.generateMethod(setter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(), setterDescriptor); + JvmPropertyAccessorSignature signature = + state.getInjector().getJetTypeMapper().mapSetterSignature(propertyDescriptor, kind); + assert signature != null; + functionCodegen.generateMethod(setter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(), + setterDescriptor); } else if (isExternallyAccessible(propertyDescriptor)) { generateDefaultSetter(p); @@ -151,7 +159,10 @@ public class PropertyCodegen { private void generateDefaultGetter(JetProperty p) { final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, p); assert propertyDescriptor != null; - int flags = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0) | (propertyDescriptor.getModality() == Modality.ABSTRACT ? Opcodes.ACC_ABSTRACT : (propertyDescriptor.getModality() == Modality.FINAL ? Opcodes.ACC_FINAL : 0)); + int flags = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0) | + (propertyDescriptor.getModality() == Modality.ABSTRACT + ? Opcodes.ACC_ABSTRACT + : (propertyDescriptor.getModality() == Modality.FINAL ? Opcodes.ACC_FINAL : 0)); generateDefaultGetter(propertyDescriptor, flags, p); } @@ -168,10 +179,12 @@ public class PropertyCodegen { flags |= Opcodes.ACC_STATIC; } - PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), propertyDescriptor.getContainingDeclaration()); + PsiElement psiElement = + BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), propertyDescriptor.getContainingDeclaration()); boolean isTrait = psiElement instanceof JetClass && ((JetClass) psiElement).isTrait(); - if (isTrait && !(kind instanceof OwnerKind.DelegateKind)) + if (isTrait && !(kind instanceof OwnerKind.DelegateKind)) { flags |= Opcodes.ACC_ABSTRACT; + } if (propertyDescriptor.getModality() == Modality.FINAL) { flags |= Opcodes.ACC_FINAL; @@ -181,19 +194,21 @@ public class PropertyCodegen { final String descriptor = signature.getJvmMethodSignature().getAsmMethod().getDescriptor(); String getterName = getterName(propertyDescriptor.getName()); MethodVisitor mv = v.newMethod(origin, flags, getterName, descriptor, null, null); + PropertyGetterDescriptor getter = propertyDescriptor.getGetter(); generateJetPropertyAnnotation(mv, signature.getPropertyTypeKotlinSignature(), signature.getJvmMethodSignature().getKotlinTypeParameter(), propertyDescriptor, - propertyDescriptor.getGetter() == null - ? propertyDescriptor.getVisibility() - : propertyDescriptor.getGetter().getVisibility()); + getter == null + ? propertyDescriptor.getVisibility() + : getter.getVisibility()); - if (propertyDescriptor.getGetter() != null) { - assert !propertyDescriptor.getGetter().hasBody(); - AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(propertyDescriptor.getGetter()); + if (getter != null) { + //noinspection ConstantConditions + assert !getter.hasBody(); + AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(getter); } if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES && (!isTrait || kind instanceof OwnerKind.DelegateKind)) { - if (propertyDescriptor.getModality() != Modality.ABSTRACT) { + if (propertyDescriptor.getModality() != Modality.ABSTRACT) { mv.visitCode(); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { StubCodegen.generateStubThrow(mv); @@ -228,8 +243,10 @@ public class PropertyCodegen { FunctionCodegen.endVisit(mv, "getter", origin); } - public static void generateJetPropertyAnnotation(MethodVisitor mv, @NotNull String kotlinType, @NotNull String typeParameters, - @NotNull PropertyDescriptor propertyDescriptor, @NotNull Visibility visibility) { + public static void generateJetPropertyAnnotation( + MethodVisitor mv, @NotNull String kotlinType, @NotNull String typeParameters, + @NotNull PropertyDescriptor propertyDescriptor, @NotNull Visibility visibility + ) { JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv); Modality modality = propertyDescriptor.getModality(); BitSet flags = CodegenUtil.getFlagsForVisibility(visibility); @@ -269,29 +286,32 @@ public class PropertyCodegen { flags |= Opcodes.ACC_STATIC; } - PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), propertyDescriptor.getContainingDeclaration()); + PsiElement psiElement = + BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), propertyDescriptor.getContainingDeclaration()); boolean isTrait = psiElement instanceof JetClass && ((JetClass) psiElement).isTrait(); - if (isTrait && !(kind instanceof OwnerKind.DelegateKind)) + if (isTrait && !(kind instanceof OwnerKind.DelegateKind)) { flags |= Opcodes.ACC_ABSTRACT; + } if (propertyDescriptor.getModality() == Modality.FINAL) { flags |= Opcodes.ACC_FINAL; } JvmPropertyAccessorSignature signature = state.getInjector().getJetTypeMapper().mapSetterSignature(propertyDescriptor, kind); + assert signature != null; final String descriptor = signature.getJvmMethodSignature().getAsmMethod().getDescriptor(); MethodVisitor mv = v.newMethod(origin, flags, setterName(propertyDescriptor.getName()), descriptor, null, null); + PropertySetterDescriptor setter = propertyDescriptor.getSetter(); + assert setter != null; generateJetPropertyAnnotation(mv, signature.getPropertyTypeKotlinSignature(), signature.getJvmMethodSignature().getKotlinTypeParameter(), propertyDescriptor, - propertyDescriptor.getSetter().getVisibility()); + setter.getVisibility()); - if (propertyDescriptor.getSetter() != null) { - assert !propertyDescriptor.getSetter().hasBody(); - AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(propertyDescriptor.getSetter()); - } + assert !setter.hasBody(); + AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(setter); if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES && (!isTrait || kind instanceof OwnerKind.DelegateKind)) { - if (propertyDescriptor.getModality() != Modality.ABSTRACT) { + if (propertyDescriptor.getModality() != Modality.ABSTRACT) { mv.visitCode(); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { StubCodegen.generateStubThrow(mv); @@ -320,8 +340,9 @@ public class PropertyCodegen { else { iv.load(paramCode, type); iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD, - state.getInjector().getJetTypeMapper().getOwner(propertyDescriptor, kind).getInternalName(), propertyDescriptor.getName().getName(), - type.getDescriptor()); + state.getInjector().getJetTypeMapper().getOwner(propertyDescriptor, kind).getInternalName(), + propertyDescriptor.getName().getName(), + type.getDescriptor()); } iv.visitInsn(Opcodes.RETURN); @@ -340,11 +361,13 @@ public class PropertyCodegen { } public void genDelegate(PropertyDescriptor declaration, PropertyDescriptor overriddenDescriptor, StackValue field) { - JvmPropertyAccessorSignature jvmPropertyAccessorSignature = state.getInjector().getJetTypeMapper().mapGetterSignature(declaration, OwnerKind.IMPLEMENTATION); + JvmPropertyAccessorSignature jvmPropertyAccessorSignature = + state.getInjector().getJetTypeMapper().mapGetterSignature(declaration, OwnerKind.IMPLEMENTATION); functionCodegen.genDelegate(declaration, overriddenDescriptor, field, jvmPropertyAccessorSignature.getJvmMethodSignature()); if (declaration.isVar()) { jvmPropertyAccessorSignature = state.getInjector().getJetTypeMapper().mapSetterSignature(declaration, OwnerKind.IMPLEMENTATION); + assert jvmPropertyAccessorSignature != null; functionCodegen.genDelegate(declaration, overriddenDescriptor, field, jvmPropertyAccessorSignature.getJvmMethodSignature()); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java index c0959ddd0a1..c2cf83c0ea0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java @@ -19,19 +19,21 @@ package org.jetbrains.jet.codegen; import com.google.common.collect.Lists; import com.intellij.openapi.util.Pair; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.codegen.signature.JvmMethodSignature; -import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -import org.jetbrains.jet.lang.descriptors.ScriptDescriptor; -import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; -import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.resolve.ScriptNameUtil; -import org.jetbrains.jet.lang.resolve.java.JdkNames; -import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.asm4.Opcodes; import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; +import org.jetbrains.jet.codegen.signature.JvmMethodSignature; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ScriptDescriptor; +import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; +import org.jetbrains.jet.lang.psi.JetDeclaration; +import org.jetbrains.jet.lang.psi.JetScript; +import org.jetbrains.jet.lang.psi.JetTypeParameterListOwner; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.ScriptNameUtil; +import org.jetbrains.jet.lang.resolve.java.JdkNames; +import org.jetbrains.jet.lang.resolve.java.JvmClassName; import javax.inject.Inject; import java.util.List; @@ -88,30 +90,31 @@ public class ScriptCodegen { } - public void generate(JetScript scriptDeclaration) { ScriptDescriptor scriptDescriptor = state.getBindingContext().get(BindingContext.SCRIPT, scriptDeclaration); + assert scriptDescriptor != null; ClassDescriptor classDescriptorForScript = closureAnnotator.classDescriptorForScriptDescriptor(scriptDescriptor); - CodegenContexts.ScriptContext context = (CodegenContexts.ScriptContext) CodegenContexts.STATIC.intoScript(scriptDescriptor, classDescriptorForScript); + CodegenContexts.ScriptContext context = + (CodegenContexts.ScriptContext) CodegenContexts.STATIC.intoScript(scriptDescriptor, classDescriptorForScript); JvmClassName className = closureAnnotator.classNameForClassDescriptor(classDescriptorForScript); ClassBuilder classBuilder = classFileFactory.newVisitor(className.getInternalName() + ".class"); classBuilder.defineClass(scriptDeclaration, - Opcodes.V1_6, - Opcodes.ACC_PUBLIC, - className.getInternalName(), - null, - JdkNames.JL_OBJECT.getInternalName(), - new String[0]); + Opcodes.V1_6, + Opcodes.ACC_PUBLIC, + className.getInternalName(), + null, + JdkNames.JL_OBJECT.getInternalName(), + new String[0]); genMembers(scriptDeclaration, context, classBuilder); genFieldsForParameters(scriptDescriptor, classBuilder); genConstructor(scriptDeclaration, scriptDescriptor, classDescriptorForScript, classBuilder, - context.intoFunction(scriptDescriptor.getScriptCodeDescriptor()), earlierScripts); + context.intoFunction(scriptDescriptor.getScriptCodeDescriptor()), earlierScripts); classBuilder.done(); } @@ -122,18 +125,21 @@ public class ScriptCodegen { @NotNull ClassDescriptor classDescriptorForScript, @NotNull ClassBuilder classBuilder, @NotNull CodegenContext context, - @NotNull List importedScripts) { + @NotNull List importedScripts + ) { Type blockType = jetTypeMapper.mapType(scriptDescriptor.getReturnType(), MapTypeMode.VALUE); - classBuilder.newField(null, Opcodes.ACC_PUBLIC|Opcodes.ACC_FINAL, ScriptNameUtil.LAST_EXPRESSION_VALUE_FIELD_NAME, blockType.getDescriptor(), null, null); + classBuilder.newField(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, ScriptNameUtil.LAST_EXPRESSION_VALUE_FIELD_NAME, + blockType.getDescriptor(), null, null); JvmMethodSignature jvmSignature = jetTypeMapper.mapScriptSignature(scriptDescriptor, importedScripts); state.setScriptConstructorMethod(jvmSignature.getAsmMethod()); MethodVisitor mv = classBuilder.newMethod( - scriptDeclaration, Opcodes.ACC_PUBLIC, jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor(), null, null); + scriptDeclaration, Opcodes.ACC_PUBLIC, jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor(), + null, null); mv.visitCode(); @@ -157,7 +163,7 @@ public class ScriptCodegen { for (int i = 0; i < scriptDescriptor.getValueParameters().size(); i++) { ValueParameterDescriptor parameter = scriptDescriptor.getValueParameters().get(i); - frameMap.enter(parameter, argTypes[i+add].getSize()); + frameMap.enter(parameter, argTypes[i + add].getSize()); } ImplementationBodyCodegen.generateInitializers( @@ -174,7 +180,8 @@ public class ScriptCodegen { instructionAdapter.load(0, className.getAsmType()); instructionAdapter.load(offset, earlierClassName.getAsmType()); offset += earlierClassName.getAsmType().getSize(); - instructionAdapter.putfield(className.getInternalName(), getScriptFieldName(earlierScript), earlierClassName.getAsmType().getDescriptor()); + instructionAdapter.putfield(className.getInternalName(), getScriptFieldName(earlierScript), + earlierClassName.getAsmType().getDescriptor()); } for (ValueParameterDescriptor parameter : scriptDescriptor.getValueParameters()) { @@ -185,10 +192,12 @@ public class ScriptCodegen { instructionAdapter.putfield(className.getInternalName(), parameter.getName().getIdentifier(), parameterType.getDescriptor()); } - StackValue stackValue = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context, state).gen(scriptDeclaration.getBlockExpression()); + StackValue stackValue = + new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context, state).gen(scriptDeclaration.getBlockExpression()); if (stackValue.type != Type.VOID_TYPE) { stackValue.put(stackValue.type, instructionAdapter); - instructionAdapter.putfield(className.getInternalName(), ScriptNameUtil.LAST_EXPRESSION_VALUE_FIELD_NAME, blockType.getDescriptor()); + instructionAdapter + .putfield(className.getInternalName(), ScriptNameUtil.LAST_EXPRESSION_VALUE_FIELD_NAME, blockType.getDescriptor()); } instructionAdapter.areturn(Type.VOID_TYPE); @@ -227,7 +236,6 @@ public class ScriptCodegen { List earlierScriptDescriptors = Lists.newArrayList(); for (Pair t : earlierScripts) { ScriptDescriptor earlierDescriptor = t.first; - JvmClassName earlierClassName = t.second; earlierScriptDescriptors.add(earlierDescriptor); } this.earlierScripts = earlierScriptDescriptors; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index 88937bf29af..e4a41bf5c70 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -19,6 +19,11 @@ package org.jetbrains.jet.codegen; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.Label; +import org.jetbrains.asm4.Opcodes; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; +import org.jetbrains.asm4.commons.Method; import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.JetExpression; @@ -27,11 +32,6 @@ import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lexer.JetTokens; -import org.jetbrains.asm4.Label; -import org.jetbrains.asm4.Opcodes; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; -import org.jetbrains.asm4.commons.Method; import java.util.List; @@ -69,8 +69,8 @@ public abstract class StackValue { * This method is called to put the value on the top of the JVM stack if depth other values have been put on the * JVM stack after this value was generated. * - * @param type the type as which the value should be put - * @param v the visitor used to generate the instructions + * @param type the type as which the value should be put + * @param v the visitor used to generate the instructions * @param depth the number of new values put onto the stack */ public void moveToTopOfStack(Type type, InstructionAdapter v, int depth) { @@ -130,7 +130,13 @@ public abstract class StackValue { return new ArrayElement(type, unbox); } - public static StackValue collectionElement(Type type, ResolvedCall getter, ResolvedCall setter, ExpressionCodegen codegen, GenerationState state) { + public static StackValue collectionElement( + Type type, + ResolvedCall getter, + ResolvedCall setter, + ExpressionCodegen codegen, + GenerationState state + ) { return new CollectionElement(type, getter, setter, codegen, state); } @@ -138,7 +144,18 @@ public abstract class StackValue { return new Field(type, owner, name, isStatic); } - public static Property property(String name, JvmClassName methodOwner, JvmClassName methodOwnerParam, Type type, boolean isStatic, boolean isInterface, boolean isSuper, Method getter, Method setter, int invokeOpcode) { + public static Property property( + String name, + JvmClassName methodOwner, + JvmClassName methodOwnerParam, + Type type, + boolean isStatic, + boolean isInterface, + boolean isSuper, + @Nullable Method getter, + @Nullable Method setter, + int invokeOpcode + ) { return new Property(name, methodOwner, methodOwnerParam, getter, setter, isStatic, isInterface, isSuper, type, invokeOpcode); } @@ -213,10 +230,12 @@ public abstract class StackValue { } protected static void pop(Type type, InstructionAdapter v) { - if (type.getSize() == 1) + if (type.getSize() == 1) { v.pop(); - else + } + else { v.pop2(); + } } protected void coerce(Type toType, InstructionAdapter v) { @@ -233,28 +252,33 @@ public abstract class StackValue { if (toType.getSort() == Type.OBJECT) { putTuple0Instance(v); } - else if (toType == Type.LONG_TYPE) + else if (toType == Type.LONG_TYPE) { v.lconst(0); - else if (toType == Type.FLOAT_TYPE) + } + else if (toType == Type.FLOAT_TYPE) { v.fconst(0); - else if (toType == Type.DOUBLE_TYPE) + } + else if (toType == Type.DOUBLE_TYPE) { v.dconst(0); - else + } + else { v.iconst(0); + } } else if (toType.equals(JetTypeMapper.TUPLE0_TYPE) && !fromType.equals(JetTypeMapper.TUPLE0_TYPE)) { pop(fromType, v); putTuple0Instance(v); } else if (toType.getSort() == Type.OBJECT && fromType.equals(JetTypeMapper.TYPE_OBJECT) || toType.getSort() == Type.ARRAY) { - v.checkcast(toType); + v.checkcast(toType); } else if (toType.getSort() == Type.OBJECT) { if (fromType.getSort() == Type.OBJECT && !toType.equals(JetTypeMapper.TYPE_OBJECT)) { v.checkcast(toType); } - else + else { box(fromType, toType, v); + } } else if (fromType.getSort() == Type.OBJECT && toType.getSort() <= Type.DOUBLE) { if (fromType.equals(JetTypeMapper.TYPE_OBJECT)) { @@ -314,14 +338,22 @@ public abstract class StackValue { return new PreIncrement(index, increment); } - public static StackValue receiver(ResolvedCall resolvedCall, StackValue receiver, ExpressionCodegen codegen, @Nullable CallableMethod callableMethod, GenerationState state) { - if (resolvedCall.getThisObject().exists() || resolvedCall.getReceiverArgument().exists()) + public static StackValue receiver( + ResolvedCall resolvedCall, + StackValue receiver, + ExpressionCodegen codegen, + @Nullable CallableMethod callableMethod, + GenerationState state + ) { + if (resolvedCall.getThisObject().exists() || resolvedCall.getReceiverArgument().exists()) { return new CallReceiver(resolvedCall, receiver, codegen, state, callableMethod); + } return receiver; } private static class None extends StackValue { public static None INSTANCE = new None(); + private None() { super(Type.VOID_TYPE); } @@ -396,19 +428,21 @@ public abstract class StackValue { @Override public void put(Type type, InstructionAdapter v) { - if (value instanceof Integer) + if (value instanceof Integer) { v.iconst((Integer) value); - else - if (value instanceof Long) + } + else if (value instanceof Long) { v.lconst((Long) value); - else - if (value instanceof Float) + } + else if (value instanceof Float) { v.fconst((Float) value); - else - if (value instanceof Double) + } + else if (value instanceof Double) { v.dconst((Double) value); - else + } + else { v.aconst(value); + } coerce(type, v); } @@ -449,8 +483,9 @@ public abstract class StackValue { throw new UnsupportedOperationException("don't know how to put a compare as a non-boolean type " + type); } putAsBoolean(v); - if(type != Type.BOOLEAN_TYPE) - box(Type.BOOLEAN_TYPE,type,v); + if (type != Type.BOOLEAN_TYPE) { + box(Type.BOOLEAN_TYPE, type, v); + } } @Override @@ -522,8 +557,9 @@ public abstract class StackValue { private Invert(StackValue operand) { super(Type.BOOLEAN_TYPE); myOperand = operand; - if (myOperand.type != Type.BOOLEAN_TYPE) + if (myOperand.type != Type.BOOLEAN_TYPE) { throw new UnsupportedOperationException("operand of ! must be boolean"); + } } @Override @@ -536,8 +572,9 @@ public abstract class StackValue { throw new UnsupportedOperationException("don't know how to put a compare as a non-boolean type"); } putAsBoolean(v); - if(type != Type.BOOLEAN_TYPE) - box(Type.BOOLEAN_TYPE,type,v); + if (type != Type.BOOLEAN_TYPE) { + box(Type.BOOLEAN_TYPE, type, v); + } } @Override @@ -571,6 +608,7 @@ public abstract class StackValue { v.dup2(); // array and index } + @Override public int receiverSize() { return 2; } @@ -587,7 +625,13 @@ public abstract class StackValue { private final FunctionDescriptor setterDescriptor; private final FunctionDescriptor getterDescriptor; - public CollectionElement(Type type, ResolvedCall resolvedGetCall, ResolvedCall resolvedSetCall, ExpressionCodegen codegen, GenerationState state) { + public CollectionElement( + Type type, + ResolvedCall resolvedGetCall, + ResolvedCall resolvedSetCall, + ExpressionCodegen codegen, + GenerationState state + ) { super(type); this.resolvedGetCall = resolvedGetCall; this.resolvedSetCall = resolvedSetCall; @@ -605,10 +649,12 @@ public abstract class StackValue { if (getter == null) { throw new UnsupportedOperationException("no getter specified"); } - if (getter instanceof CallableMethod) - ((CallableMethod)getter).invoke(v); - else - ((IntrinsicMethod)getter).generate(codegen, v, type, null, null, null, state); + if (getter instanceof CallableMethod) { + ((CallableMethod) getter).invoke(v); + } + else { + ((IntrinsicMethod) getter).generate(codegen, v, type, null, null, null, state); + } coerce(type, v); } @@ -621,17 +667,19 @@ public abstract class StackValue { CallableMethod method = (CallableMethod) setter; Method asmMethod = method.getSignature().getAsmMethod(); Type[] argumentTypes = asmMethod.getArgumentTypes(); - coerce(topOfStackType, argumentTypes[argumentTypes.length-1], v); + coerce(topOfStackType, argumentTypes[argumentTypes.length - 1], v); method.invoke(v); Type returnType = asmMethod.getReturnType(); if (returnType != Type.VOID_TYPE) { pop(returnType, v); } } - else + else { ((IntrinsicMethod) setter).generate(codegen, v, null, null, null, null, state); + } } + @Override public int receiverSize() { if (isStandardStack(resolvedGetCall, 1) && isStandardStack(resolvedSetCall, 2)) { return 2; @@ -650,27 +698,27 @@ public abstract class StackValue { int size = 0; int lastIndex = frame.enterTemp(); frame.leaveTemp(); - + // indexes List valueParameters = resolvedGetCall.getResultingDescriptor().getValueParameters(); int firstParamIndex = -1; - for(int i = valueParameters.size()-1; i >= 0; --i) { + for (int i = valueParameters.size() - 1; i >= 0; --i) { Type type = codegen.typeMapper.mapType(valueParameters.get(i).getType(), MapTypeMode.VALUE); int sz = type.getSize(); frame.enterTemp(sz); lastIndex += sz; size += sz; - v.store((firstParamIndex = lastIndex)-sz, type); + v.store((firstParamIndex = lastIndex) - sz, type); } List typeParameters = resolvedGetCall.getResultingDescriptor().getTypeParameters(); int firstTypeParamIndex = -1; - for(int i = typeParameters.size()-1; i >= 0; --i) { + for (int i = typeParameters.size() - 1; i >= 0; --i) { if (typeParameters.get(i).isReified()) { frame.enterTemp(); lastIndex++; size++; - v.store(firstTypeParamIndex = lastIndex-1, JetTypeMapper.TYPE_OBJECT); + v.store(firstTypeParamIndex = lastIndex - 1, JetTypeMapper.TYPE_OBJECT); } } @@ -682,7 +730,7 @@ public abstract class StackValue { frame.enterTemp(sz); lastIndex += sz; size += sz; - v.store((receiverIndex = lastIndex)-sz, type); + v.store((receiverIndex = lastIndex) - sz, type); } ReceiverDescriptor thisObject = resolvedGetCall.getThisObject(); @@ -691,17 +739,17 @@ public abstract class StackValue { frame.enterTemp(); lastIndex++; size++; - v.store((thisIndex = lastIndex)-1, JetTypeMapper.TYPE_OBJECT); + v.store((thisIndex = lastIndex) - 1, JetTypeMapper.TYPE_OBJECT); } - + // for setter - int realReceiverIndex; + int realReceiverIndex; Type realReceiverType; if (thisIndex != -1) { if (receiverIndex != -1) { realReceiverIndex = receiverIndex; - realReceiverType = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE); + realReceiverType = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE); } else { realReceiverIndex = thisIndex; @@ -710,7 +758,7 @@ public abstract class StackValue { } else { if (receiverIndex != -1) { - realReceiverType = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE); + realReceiverType = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE); realReceiverIndex = receiverIndex; } else { @@ -734,38 +782,38 @@ public abstract class StackValue { } int index = firstParamIndex; - for(int i = 0; i != valueParameters.size(); ++i) { + for (int i = 0; i != valueParameters.size(); ++i) { Type type = codegen.typeMapper.mapType(valueParameters.get(i).getType(), MapTypeMode.VALUE); int sz = type.getSize(); - v.load(index-sz, type); + v.load(index - sz, type); index -= sz; } // restoring original if (thisIndex != -1) { - v.load(thisIndex-1, JetTypeMapper.TYPE_OBJECT); + v.load(thisIndex - 1, JetTypeMapper.TYPE_OBJECT); } - + if (receiverIndex != -1) { Type type = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE); - v.load(receiverIndex-type.getSize(), type); + v.load(receiverIndex - type.getSize(), type); } if (firstTypeParamIndex != -1) { index = firstTypeParamIndex; - for(int i = 0; i != typeParameters.size(); ++i) { + for (int i = 0; i != typeParameters.size(); ++i) { if (typeParameters.get(i).isReified()) { - v.load(index-1, JetTypeMapper.TYPE_OBJECT); + v.load(index - 1, JetTypeMapper.TYPE_OBJECT); index--; } } } - + index = firstParamIndex; - for(int i = 0; i != valueParameters.size(); ++i) { + for (int i = 0; i != valueParameters.size(); ++i) { Type type = codegen.typeMapper.mapType(valueParameters.get(i).getType(), MapTypeMode.VALUE); int sz = type.getSize(); - v.load(index-sz, type); + v.load(index - sz, type); index -= sz; } @@ -774,30 +822,37 @@ public abstract class StackValue { } private boolean isStandardStack(ResolvedCall call, int valueParamsSize) { - if (call == null) + if (call == null) { return true; + } for (TypeParameterDescriptor typeParameterDescriptor : call.getResultingDescriptor().getTypeParameters()) { - if (typeParameterDescriptor.isReified()) + if (typeParameterDescriptor.isReified()) { return false; + } } List valueParameters = call.getResultingDescriptor().getValueParameters(); - if (valueParameters.size() != valueParamsSize) + if (valueParameters.size() != valueParamsSize) { return false; + } for (ValueParameterDescriptor valueParameter : valueParameters) { - if (codegen.typeMapper.mapType(valueParameter.getType(), MapTypeMode.VALUE).getSize() != 1) + if (codegen.typeMapper.mapType(valueParameter.getType(), MapTypeMode.VALUE).getSize() != 1) { return false; + } } if (call.getThisObject().exists()) { - if (call.getReceiverArgument().exists()) + if (call.getReceiverArgument().exists()) { return false; + } } else { - if (codegen.typeMapper.mapType(call.getResultingDescriptor().getReceiverParameter().getType(), MapTypeMode.VALUE).getSize() != 1) + if (codegen.typeMapper.mapType(call.getResultingDescriptor().getReceiverParameter().getType(), MapTypeMode.VALUE) + .getSize() != 1) { return false; + } } return true; @@ -830,6 +885,7 @@ public abstract class StackValue { } } + @Override public int receiverSize() { return isStatic ? 0 : 1; } @@ -857,8 +913,10 @@ public abstract class StackValue { private final boolean isSuper; private final int invokeOpcode; - public Property(@NotNull String name, @NotNull JvmClassName methodOwner, @NotNull JvmClassName methodOwnerParam, - Method getter, Method setter, boolean aStatic, boolean isInterface, boolean isSuper, Type type, int invokeOpcode) { + public Property( + @NotNull String name, @NotNull JvmClassName methodOwner, @NotNull JvmClassName methodOwnerParam, + Method getter, Method setter, boolean aStatic, boolean isInterface, boolean isSuper, Type type, int invokeOpcode + ) { super(type); this.name = name; this.methodOwner = methodOwner; @@ -879,15 +937,18 @@ public abstract class StackValue { @Override public void put(Type type, InstructionAdapter v) { if (isSuper && isInterface) { - v.visitMethodInsn(Opcodes.INVOKESTATIC, methodOwner.getInternalName(), getter.getName(), getter.getDescriptor().replace("(", "(" + methodOwnerParam.getDescriptor())); + assert getter != null; + v.visitMethodInsn(Opcodes.INVOKESTATIC, methodOwner.getInternalName(), getter.getName(), + getter.getDescriptor().replace("(", "(" + methodOwnerParam.getDescriptor())); } else { - if (getter == null) { - v.visitFieldInsn(isStatic ? Opcodes.GETSTATIC : Opcodes.GETFIELD, methodOwner.getInternalName(), name, this.type.getDescriptor()); - } - else { - v.visitMethodInsn(invokeOpcode, methodOwner.getInternalName(), getter.getName(), getter.getDescriptor()); - } + if (getter == null) { + v.visitFieldInsn(isStatic ? Opcodes.GETSTATIC : Opcodes.GETFIELD, methodOwner.getInternalName(), name, + this.type.getDescriptor()); + } + else { + v.visitMethodInsn(invokeOpcode, methodOwner.getInternalName(), getter.getName(), getter.getDescriptor()); + } } coerce(type, v); } @@ -895,10 +956,13 @@ public abstract class StackValue { @Override public void store(Type topOfStackType, InstructionAdapter v) { if (isSuper && isInterface) { - v.visitMethodInsn(Opcodes.INVOKESTATIC, methodOwner.getInternalName(), setter.getName(), setter.getDescriptor().replace("(", "(" + methodOwnerParam.getDescriptor())); + assert setter != null; + v.visitMethodInsn(Opcodes.INVOKESTATIC, methodOwner.getInternalName(), setter.getName(), + setter.getDescriptor().replace("(", "(" + methodOwnerParam.getDescriptor())); } else if (setter == null) { - v.visitFieldInsn(isStatic ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD, methodOwner.getInternalName(), name, this.type.getDescriptor()); + v.visitFieldInsn(isStatic ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD, methodOwner.getInternalName(), name, + this.type.getDescriptor()); } else { v.visitMethodInsn(invokeOpcode, methodOwner.getInternalName(), setter.getName(), setter.getDescriptor()); @@ -912,6 +976,7 @@ public abstract class StackValue { } } + @Override public int receiverSize() { return isStatic ? 0 : 1; } @@ -975,7 +1040,7 @@ public abstract class StackValue { } public static Type sharedTypeForType(Type type) { - switch(type.getSort()) { + switch (type.getSort()) { case Type.OBJECT: case Type.ARRAY: return JetTypeMapper.TYPE_SHARED_VAR; @@ -1010,8 +1075,9 @@ public abstract class StackValue { } public static Type refType(Type type) { - if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) + if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) { return JetTypeMapper.TYPE_OBJECT; + } return type; } @@ -1031,6 +1097,7 @@ public abstract class StackValue { v.dup(); } + @Override public int receiverSize() { return 1; } @@ -1135,20 +1202,27 @@ public abstract class StackValue { private ResolvedCall resolvedCall; StackValue receiver; private ExpressionCodegen codegen; - @NotNull - private final GenerationState state; private CallableMethod callableMethod; - public CallReceiver(ResolvedCall resolvedCall, StackValue receiver, ExpressionCodegen codegen, @NotNull GenerationState state, CallableMethod callableMethod) { + public CallReceiver( + ResolvedCall resolvedCall, + StackValue receiver, + ExpressionCodegen codegen, + @NotNull GenerationState state, + CallableMethod callableMethod + ) { super(calcType(resolvedCall, codegen, callableMethod)); this.resolvedCall = resolvedCall; this.receiver = receiver; this.codegen = codegen; - this.state = state; this.callableMethod = callableMethod; } - private static Type calcType(ResolvedCall resolvedCall, ExpressionCodegen codegen, CallableMethod callableMethod) { + private static Type calcType( + ResolvedCall resolvedCall, + ExpressionCodegen codegen, + CallableMethod callableMethod + ) { ReceiverDescriptor thisObject = resolvedCall.getThisObject(); ReceiverDescriptor receiverArgument = resolvedCall.getReceiverArgument(); @@ -1174,10 +1248,12 @@ public abstract class StackValue { } else { if (receiverArgument.exists()) { - if (callableMethod != null) + if (callableMethod != null) { return callableMethod.getReceiverClass(); - else + } + else { return codegen.typeMapper.mapType(descriptor.getReceiverParameter().getType(), MapTypeMode.VALUE); + } } else { return Type.VOID_TYPE; @@ -1197,7 +1273,8 @@ public abstract class StackValue { codegen.generateFromResolvedCall(thisObject, callableMethod.getOwner().getAsmType()); } else { - codegen.generateFromResolvedCall(thisObject, codegen.typeMapper.mapType(descriptor.getExpectedThisObject().getType(), MapTypeMode.VALUE)); + codegen.generateFromResolvedCall(thisObject, codegen.typeMapper + .mapType(descriptor.getExpectedThisObject().getType(), MapTypeMode.VALUE)); } genReceiver(v, receiverArgument, type, descriptor.getReceiverParameter(), 1); } @@ -1212,8 +1289,10 @@ public abstract class StackValue { } } - private void genReceiver(InstructionAdapter v, ReceiverDescriptor receiverArgument, Type type, - @Nullable ReceiverDescriptor receiverParameter, int depth) { + private void genReceiver( + InstructionAdapter v, ReceiverDescriptor receiverArgument, Type type, + @Nullable ReceiverDescriptor receiverParameter, int depth + ) { if (receiver == StackValue.none()) { if (receiverParameter != null) { Type receiverType = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StubCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/StubCodegen.java index 1b6fd156bb2..258040827d4 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StubCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StubCodegen.java @@ -28,11 +28,12 @@ public class StubCodegen { } public static void generateStubThrow(MethodVisitor mv) { - new InstructionAdapter(mv).anew(Type.getObjectType("java/lang/RuntimeException")); - new InstructionAdapter(mv).dup(); - new InstructionAdapter(mv).aconst("Stubs are for compiler only, do not add them to runtime classpath"); - new InstructionAdapter(mv).invokespecial("java/lang/RuntimeException", "", "(Ljava/lang/String;)V"); - new InstructionAdapter(mv).athrow(); + InstructionAdapter iv = new InstructionAdapter(mv); + iv.anew(Type.getObjectType("java/lang/RuntimeException")); + iv.dup(); + iv.aconst("Stubs are for compiler only, do not add them to runtime classpath"); + iv.invokespecial("java/lang/RuntimeException", "", "(Ljava/lang/String;)V"); + iv.athrow(); } public static void generateStubCode(MethodVisitor mv) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java index ff2f40e7c90..86530e482db 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java @@ -16,13 +16,13 @@ package org.jetbrains.jet.codegen; +import org.jetbrains.asm4.Opcodes; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassKind; import org.jetbrains.jet.lang.psi.JetClassOrObject; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.lang.JetStandardClasses; -import org.jetbrains.asm4.Opcodes; import java.util.List; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayGet.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayGet.java index 4c19c781649..d5aa57215df 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayGet.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayGet.java @@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -33,7 +33,15 @@ import java.util.List; */ public class ArrayGet implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { receiver.put(JetTypeMapper.TYPE_OBJECT, v); Type type = JetTypeMapper.correctElementType(receiver.type); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayIndices.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayIndices.java index 6cde0728790..27ba2ad13cb 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayIndices.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayIndices.java @@ -18,19 +18,27 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; public class ArrayIndices implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { receiver.put(JetTypeMapper.TYPE_OBJECT, v); v.arraylength(); v.invokestatic("jet/IntRange", "count", "(I)Ljet/IntRange;"); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayIterator.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayIterator.java index 47b17d80742..1e60efce96d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayIterator.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayIterator.java @@ -41,10 +41,20 @@ import java.util.List; */ public class ArrayIterator implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { receiver.put(JetTypeMapper.TYPE_OBJECT, v); JetCallExpression call = (JetCallExpression) element; - FunctionDescriptor funDescriptor = (FunctionDescriptor) codegen.getBindingContext().get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) call.getCalleeExpression()); + FunctionDescriptor funDescriptor = (FunctionDescriptor) codegen.getBindingContext() + .get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) call.getCalleeExpression()); + assert funDescriptor != null; ClassDescriptor containingDeclaration = (ClassDescriptor) funDescriptor.getContainingDeclaration().getOriginal(); if (JetStandardLibraryNames.ARRAY.is(containingDeclaration)) { v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([Ljava/lang/Object;)Ljet/Iterator;"); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArraySet.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArraySet.java index beb942e9e20..fbb246db59a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArraySet.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArraySet.java @@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -33,7 +33,15 @@ import java.util.List; */ public class ArraySet implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { receiver.put(JetTypeMapper.TYPE_OBJECT, v); Type type = JetTypeMapper.correctElementType(receiver.type); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArraySize.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArraySize.java index 960509ee3eb..8b77a3f9915 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArraySize.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArraySize.java @@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -33,7 +33,15 @@ import java.util.List; */ public class ArraySize implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { receiver.put(JetTypeMapper.TYPE_OBJECT, v); v.arraylength(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/BinaryOp.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/BinaryOp.java index 6c708ab6d8e..c535fa07fb3 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/BinaryOp.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/BinaryOp.java @@ -18,14 +18,14 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Opcodes; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Opcodes; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -40,7 +40,15 @@ public class BinaryOp implements IntrinsicMethod { } @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { boolean nullable = expectedType.getSort() == Type.OBJECT; if (nullable) { expectedType = JetTypeMapper.unboxType(expectedType); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/CompareTo.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/CompareTo.java index df3280f44ad..29b84bfb670 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/CompareTo.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/CompareTo.java @@ -19,12 +19,12 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -33,12 +33,21 @@ import java.util.List; */ public class CompareTo implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, @Nullable List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + @Nullable PsiElement element, + @Nullable List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { assert arguments != null; receiver.put(receiver.type, v); codegen.gen(arguments.get(0), receiver.type); - if (receiver.type == Type.BYTE_TYPE || receiver.type == Type.SHORT_TYPE || receiver.type == Type.CHAR_TYPE) + if (receiver.type == Type.BYTE_TYPE || receiver.type == Type.SHORT_TYPE || receiver.type == Type.CHAR_TYPE) { v.sub(Type.INT_TYPE); + } else if (receiver.type == Type.INT_TYPE) { v.invokestatic("jet/runtime/Intrinsics", "compare", "(II)I"); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Concat.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Concat.java index 0fad37b7638..c115466b724 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Concat.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Concat.java @@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -33,7 +33,15 @@ import java.util.List; */ public class Concat implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { if (receiver == null || receiver == StackValue.none()) { // LHS + RHS codegen.generateStringBuilderConstructor(); codegen.invokeAppend(arguments.get(0)); // StringBuilder(LHS) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/EmptyRange.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/EmptyRange.java index 67517bb264f..33622fbca87 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/EmptyRange.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/EmptyRange.java @@ -42,13 +42,15 @@ public class EmptyRange implements IntrinsicMethod { } @Override - public StackValue generate(ExpressionCodegen codegen, + public StackValue generate( + ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, @Nullable List arguments, StackValue receiver, - @NotNull GenerationState state) { + @NotNull GenerationState state + ) { JvmClassName name = JvmClassName.byFqNameWithoutInnerClasses(elementType.getRangeClassName().getFqName()); v.getstatic(name.toString(), "EMPTY", "L" + name + ";"); return StackValue.onStack(expectedType); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/EnumValueOf.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/EnumValueOf.java index bd6e321409f..94eef199550 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/EnumValueOf.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/EnumValueOf.java @@ -27,7 +27,7 @@ import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; -import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType; +import org.jetbrains.jet.lang.types.JetType; import java.util.List; @@ -36,15 +36,22 @@ import java.util.List; */ public class EnumValueOf implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, - @Nullable List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, + @Nullable List arguments, StackValue receiver, @NotNull GenerationState state + ) { JetCallExpression call = (JetCallExpression) element; - ResolvedCall resolvedCall = codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression()); + ResolvedCall resolvedCall = + codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression()); + assert resolvedCall != null; CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor(); + JetType returnType = resultingDescriptor.getReturnType(); + assert returnType != null; Type type = state.getInjector().getJetTypeMapper().mapType( - resultingDescriptor.getReturnType(), MapTypeMode.VALUE); - codegen.gen(arguments.get(0),JetTypeMapper.JL_STRING_TYPE); - v.invokestatic(type.getInternalName(),"valueOf","(Ljava/lang/String;)" + type.getDescriptor()); + returnType, MapTypeMode.VALUE); + assert arguments != null; + codegen.gen(arguments.get(0), JetTypeMapper.JL_STRING_TYPE); + v.invokestatic(type.getInternalName(), "valueOf", "(Ljava/lang/String;)" + type.getDescriptor()); StackValue.onStack(type).put(expectedType, v); return StackValue.onStack(expectedType); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/EnumValues.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/EnumValues.java index 45f805f873c..a76d517bde2 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/EnumValues.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/EnumValues.java @@ -21,12 +21,16 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; -import org.jetbrains.jet.codegen.*; +import org.jetbrains.jet.codegen.ExpressionCodegen; +import org.jetbrains.jet.codegen.GenerationState; +import org.jetbrains.jet.codegen.MapTypeMode; +import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; +import org.jetbrains.jet.lang.types.JetType; import java.util.List; @@ -35,13 +39,19 @@ import java.util.List; */ public class EnumValues implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, - @Nullable List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, + @Nullable List arguments, StackValue receiver, @NotNull GenerationState state + ) { JetCallExpression call = (JetCallExpression) element; - ResolvedCall resolvedCall = codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression()); + ResolvedCall resolvedCall = + codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression()); + assert resolvedCall != null; CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor(); + JetType returnType = resultingDescriptor.getReturnType(); + assert returnType != null; Type type = state.getInjector().getJetTypeMapper().mapType( - resultingDescriptor.getReturnType(), MapTypeMode.VALUE); + returnType, MapTypeMode.VALUE); v.invokestatic(type.getElementType().getInternalName(), "values", "()" + type); StackValue.onStack(type).put(expectedType, v); return StackValue.onStack(expectedType); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Equals.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Equals.java index 840db7d6acf..54b5287e5cb 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Equals.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Equals.java @@ -18,6 +18,8 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.JetTypeMapper; @@ -27,8 +29,6 @@ import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lexer.JetTokens; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -37,7 +37,15 @@ import java.util.List; */ public class Equals implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { boolean leftNullable = true; JetExpression rightExpr; @@ -47,14 +55,17 @@ public class Equals implements IntrinsicMethod { JetExpression calleeExpression = jetCallExpression.getCalleeExpression(); if (calleeExpression != null) { JetType leftType = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, calleeExpression); - if (leftType != null) + if (leftType != null) { leftNullable = leftType.isNullable(); + } } rightExpr = arguments.get(0); } else { JetExpression leftExpr = arguments.get(0); - leftNullable = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, leftExpr).isNullable(); + JetType leftType = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, leftExpr); + assert leftType != null; + leftNullable = leftType.isNullable(); codegen.gen(leftExpr).put(JetTypeMapper.TYPE_OBJECT, v); rightExpr = arguments.get(1); } @@ -62,6 +73,9 @@ public class Equals implements IntrinsicMethod { JetType rightType = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, rightExpr); codegen.gen(rightExpr).put(JetTypeMapper.TYPE_OBJECT, v); - return codegen.generateEqualsForExpressionsOnStack(JetTokens.EQEQ, JetTypeMapper.TYPE_OBJECT, JetTypeMapper.TYPE_OBJECT, leftNullable, rightType.isNullable()); + assert rightType != null; + return codegen + .generateEqualsForExpressionsOnStack(JetTokens.EQEQ, JetTypeMapper.TYPE_OBJECT, JetTypeMapper.TYPE_OBJECT, leftNullable, + rightType.isNullable()); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/HashCode.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/HashCode.java index bc9e0e0a222..e4c97194e3f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/HashCode.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/HashCode.java @@ -35,13 +35,15 @@ import java.util.List; */ public class HashCode implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, + public StackValue generate( + ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, @Nullable List arguments, StackValue receiver, - @NotNull GenerationState state) { + @NotNull GenerationState state + ) { receiver.put(JetTypeMapper.TYPE_OBJECT, v); v.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I"); return StackValue.onStack(Type.INT_TYPE); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IdentityEquals.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IdentityEquals.java index 1836a0a98f6..092c007c52a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IdentityEquals.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IdentityEquals.java @@ -18,6 +18,8 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.JetTypeMapper; @@ -25,11 +27,7 @@ import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetBinaryExpression; import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lexer.JetTokens; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -38,14 +36,22 @@ import java.util.List; */ public class IdentityEquals implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { if (element instanceof JetCallExpression) { receiver.put(JetTypeMapper.TYPE_OBJECT, v); codegen.gen(arguments.get(0)).put(JetTypeMapper.TYPE_OBJECT, v); } else { assert element instanceof JetBinaryExpression; - JetBinaryExpression e = (JetBinaryExpression)element; + JetBinaryExpression e = (JetBinaryExpression) element; codegen.gen(e.getLeft()).put(JetTypeMapper.TYPE_OBJECT, v); codegen.gen(e.getRight()).put(JetTypeMapper.TYPE_OBJECT, v); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java index d0b0f65d20c..2ac4a99c328 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java @@ -18,6 +18,8 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.JetTypeMapper; @@ -25,8 +27,6 @@ import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetParenthesizedExpression; import org.jetbrains.jet.lang.psi.JetReferenceExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -41,15 +41,23 @@ public class Increment implements IntrinsicMethod { } @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { boolean nullable = expectedType.getSort() == Type.OBJECT; if (nullable) { expectedType = JetTypeMapper.unboxType(expectedType); } if (arguments.size() > 0) { JetExpression operand = arguments.get(0); - while(operand instanceof JetParenthesizedExpression) { - operand = ((JetParenthesizedExpression)operand).getExpression(); + while (operand instanceof JetParenthesizedExpression) { + operand = ((JetParenthesizedExpression) operand).getExpression(); } if (operand instanceof JetReferenceExpression) { final int index = codegen.indexOfLocal((JetReferenceExpression) operand); @@ -58,8 +66,8 @@ public class Increment implements IntrinsicMethod { } } StackValue value = codegen.genQualified(receiver, operand); - value. dupReceiver(v); - value. dupReceiver(v); + value.dupReceiver(v); + value.dupReceiver(v); value.put(expectedType, v); plusMinus(v, expectedType); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethod.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethod.java index a2ccca59983..60b00d224e9 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethod.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethod.java @@ -19,13 +19,13 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.Callable; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -33,6 +33,8 @@ import java.util.List; * @author yole */ public interface IntrinsicMethod extends Callable { - StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, - @Nullable List arguments, StackValue receiver, @NotNull GenerationState state); + StackValue generate( + ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, + @Nullable List arguments, @Nullable StackValue receiver, @NotNull GenerationState state + ); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java index 982705e6267..a6621dfc241 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java @@ -20,10 +20,7 @@ import com.google.common.collect.ImmutableList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.asm4.Opcodes; -import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor; -import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.resolve.DescriptorUtils; @@ -141,8 +138,8 @@ public class IntrinsicMethods { for (PrimitiveType type : PrimitiveType.values()) { declareIntrinsicFunction(type.getTypeName(), Name.identifier("compareTo"), 1, new CompareTo()); } -// declareIntrinsicFunction("Any", "equals", 1, new Equals()); -// + // declareIntrinsicFunction("Any", "equals", 1, new Equals()); + // declareIntrinsicProperty(Name.identifier("CharSequence"), Name.identifier("length"), new StringLength()); declareIntrinsicProperty(Name.identifier("String"), Name.identifier("length"), new StringLength()); @@ -196,20 +193,6 @@ public class IntrinsicMethods { intrinsicsMap.registerIntrinsic(JetStandardClasses.STANDARD_CLASSES_FQNAME.child(className), functionName, arity, implementation); } - public IntrinsicMethod isIntrinsicMethod(DeclarationDescriptor descriptor) { - List annotations = descriptor.getAnnotations(); - if (annotations != null) { - for (AnnotationDescriptor annotation : annotations) { - if("Intrinsic".equals(annotation.getType().getConstructor().getDeclarationDescriptor().getName().getName())) { - String value = (String) annotation.getValueArguments().get(0).getValue(); - IntrinsicMethod intrinsicMethod = namedMethods.get(value); - if (intrinsicMethod != null) { return intrinsicMethod; } - } - } - } - return null; - } - @Nullable public IntrinsicMethod getIntrinsic(@NotNull CallableMemberDescriptor descriptor) { IntrinsicMethod intrinsicMethod = intrinsicsMap.getIntrinsic(descriptor); @@ -226,11 +209,11 @@ public class IntrinsicMethods { } } - if(isEnumClassObject(functionDescriptor.getContainingDeclaration())) { - if("values".equals(functionDescriptor.getName().getName())) { + if (isEnumClassObject(functionDescriptor.getContainingDeclaration())) { + if ("values".equals(functionDescriptor.getName().getName())) { return ENUM_VALUES; } - if("valueOf".equals(functionDescriptor.getName().getName())) { + if ("valueOf".equals(functionDescriptor.getName().getName())) { return ENUM_VALUE_OF; } } @@ -239,10 +222,14 @@ public class IntrinsicMethods { List annotations = descriptor.getAnnotations(); if (annotations != null) { for (AnnotationDescriptor annotation : annotations) { - if("Intrinsic".equals(annotation.getType().getConstructor().getDeclarationDescriptor().getName().getName())) { + ClassifierDescriptor classifierDescriptor = annotation.getType().getConstructor().getDeclarationDescriptor(); + assert classifierDescriptor != null; + if ("Intrinsic".equals(classifierDescriptor.getName().getName())) { String value = (String) annotation.getValueArguments().get(0).getValue(); intrinsicMethod = namedMethods.get(value); - if (intrinsicMethod != null) { break; } + if (intrinsicMethod != null) { + break; + } } } } @@ -250,16 +237,18 @@ public class IntrinsicMethods { } private static boolean isEnumClassObject(DeclarationDescriptor declaration) { - if(declaration instanceof ClassDescriptor) { + if (declaration instanceof ClassDescriptor) { ClassDescriptor descriptor = (ClassDescriptor) declaration; - if(descriptor.getContainingDeclaration() instanceof ClassDescriptor) { + if (descriptor.getContainingDeclaration() instanceof ClassDescriptor) { ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration(); //noinspection ConstantConditions - if(containingDeclaration != null && containingDeclaration.getClassObjectDescriptor() != null && containingDeclaration.getClassObjectDescriptor().equals(descriptor)) { + if (containingDeclaration != null && + containingDeclaration.getClassObjectDescriptor() != null && + containingDeclaration.getClassObjectDescriptor().equals(descriptor)) { return true; } } } - return false; //To change body of created methods use File | Settings | File Templates. + return false; } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicsMap.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicsMap.java index 631ce95ebf8..6358755aba0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicsMap.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicsMap.java @@ -70,7 +70,7 @@ class IntrinsicsMap { } } - private int valueParameterCountForKey(@NotNull CallableMemberDescriptor member) { + private static int valueParameterCountForKey(@NotNull CallableMemberDescriptor member) { if (member instanceof PropertyDescriptor) { return -1; } @@ -79,7 +79,7 @@ class IntrinsicsMap { } } - private Map intrinsicsMap = Maps.newHashMap(); + private final Map intrinsicsMap = Maps.newHashMap(); /** @@ -105,5 +105,4 @@ class IntrinsicsMap { valueParameterCountForKey(descriptor)); return intrinsicsMap.get(key); } - } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Inv.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Inv.java index fa7a7dee031..c92acc431e7 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Inv.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Inv.java @@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -34,7 +34,15 @@ import java.util.List; */ public class Inv implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { boolean nullable = expectedType.getSort() == Type.OBJECT; if (nullable) { expectedType = JetTypeMapper.unboxType(expectedType); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IteratorIterator.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IteratorIterator.java index 34189aa98b9..d263eff406e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IteratorIterator.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IteratorIterator.java @@ -19,12 +19,12 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -33,7 +33,15 @@ import java.util.List; */ public class IteratorIterator implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, @Nullable List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + @Nullable PsiElement element, + @Nullable List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { return receiver; } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IteratorNext.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IteratorNext.java index 731ebcd0123..2d4e72aa8cc 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IteratorNext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IteratorNext.java @@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -33,26 +33,43 @@ import java.util.List; */ public class IteratorNext implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { String name; - if (expectedType == Type.CHAR_TYPE) + if (expectedType == Type.CHAR_TYPE) { name = "Char"; - else if (expectedType == Type.BOOLEAN_TYPE) + } + else if (expectedType == Type.BOOLEAN_TYPE) { name = "Boolean"; - else if (expectedType == Type.BYTE_TYPE) + } + else if (expectedType == Type.BYTE_TYPE) { name = "Byte"; - else if (expectedType == Type.SHORT_TYPE) + } + else if (expectedType == Type.SHORT_TYPE) { name = "Short"; - else if (expectedType == Type.INT_TYPE) + } + else if (expectedType == Type.INT_TYPE) { name = "Int"; - else if (expectedType == Type.LONG_TYPE) + } + else if (expectedType == Type.LONG_TYPE) { name = "Long"; - else if (expectedType == Type.FLOAT_TYPE) + } + else if (expectedType == Type.FLOAT_TYPE) { name = "Float"; - else if (expectedType == Type.DOUBLE_TYPE) + } + else if (expectedType == Type.DOUBLE_TYPE) { name = "Double"; - else + } + else { throw new UnsupportedOperationException(); + } receiver.put(JetTypeMapper.TYPE_OBJECT, v); v.invokevirtual("jet/" + name + "Iterator", "next" + name, "()" + expectedType.getDescriptor()); return StackValue.onStack(expectedType); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/JavaClassArray.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/JavaClassArray.java index 3645317b35f..f0313b944bd 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/JavaClassArray.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/JavaClassArray.java @@ -19,6 +19,8 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.StackValue; @@ -30,8 +32,6 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.ResolvedValueArgument; import org.jetbrains.jet.lang.resolve.calls.VarargValueArgument; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; import java.util.Map; @@ -41,17 +41,20 @@ import java.util.Map; */ public class JavaClassArray implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, - InstructionAdapter v, - @NotNull Type expectedType, - @Nullable PsiElement element, - @Nullable List arguments, - StackValue receiver, - @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + @Nullable PsiElement element, + @Nullable List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { ResolvedCall call = - codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, ((JetCallExpression)element).getCalleeExpression()); - Map.Entry next = call.getValueArguments().entrySet().iterator().next(); - codegen.genVarargs(next.getKey(), (VarargValueArgument)next.getValue()); + codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, ((JetCallExpression) element).getCalleeExpression()); + assert call != null; + Map.Entry next = call.getValueArguments().entrySet().iterator().next(); + codegen.genVarargs(next.getKey(), (VarargValueArgument) next.getValue()); return StackValue.onStack(expectedType); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/JavaClassFunction.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/JavaClassFunction.java index 6c73cc6d6c2..cadb011d4a5 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/JavaClassFunction.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/JavaClassFunction.java @@ -19,15 +19,16 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.*; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType; +import org.jetbrains.jet.lang.types.JetType; import java.util.List; @@ -36,13 +37,19 @@ import java.util.List; */ public class JavaClassFunction implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, - @Nullable List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, + @Nullable List arguments, StackValue receiver, @NotNull GenerationState state + ) { JetCallExpression call = (JetCallExpression) element; - ResolvedCall resolvedCall = codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression()); + ResolvedCall resolvedCall = + codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression()); + assert resolvedCall != null; CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor(); + JetType returnType = resultingDescriptor.getReturnType(); + assert returnType != null; Type type = state.getInjector().getJetTypeMapper().mapType( - resultingDescriptor.getReturnType().getArguments().get(0).getType(), MapTypeMode.VALUE); + returnType.getArguments().get(0).getType(), MapTypeMode.VALUE); JvmPrimitiveType primitiveType = JvmPrimitiveType.getByAsmType(type); if (primitiveType != null) { v.getstatic(primitiveType.getWrapper().getAsmType().getInternalName(), "TYPE", "Ljava/lang/Class;"); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/JavaClassProperty.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/JavaClassProperty.java index 177f557030f..419c65374c5 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/JavaClassProperty.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/JavaClassProperty.java @@ -19,13 +19,13 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType; import java.util.List; @@ -35,7 +35,15 @@ import java.util.List; */ public class JavaClassProperty implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, @Nullable List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + @Nullable PsiElement element, + @Nullable List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { receiver.put(receiver.type, v); JvmPrimitiveType primitiveType = JvmPrimitiveType.getByAsmType(receiver.type); if (primitiveType != null) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/NewArray.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/NewArray.java index 68779258fc5..8b94205e91d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/NewArray.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/NewArray.java @@ -18,14 +18,14 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -34,8 +34,17 @@ import java.util.List; */ public class NewArray implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { - codegen.generateNewArray((JetCallExpression) element, codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, (JetExpression) element)); + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { + codegen.generateNewArray((JetCallExpression) element, + codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, (JetExpression) element)); return StackValue.onStack(expectedType); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Not.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Not.java index dd09fd93e2e..293938128b2 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Not.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Not.java @@ -18,12 +18,12 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -32,7 +32,15 @@ import java.util.List; */ public class Not implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { final StackValue stackValue; if (arguments.size() == 1) { stackValue = codegen.gen(arguments.get(0)); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/NumberCast.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/NumberCast.java index 1050e01c99f..3027e5ec5d1 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/NumberCast.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/NumberCast.java @@ -18,12 +18,12 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -32,7 +32,15 @@ import java.util.List; */ public class NumberCast implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { receiver.put(expectedType, v); return StackValue.onStack(expectedType); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/PsiMethodCall.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/PsiMethodCall.java index 08ef6dbb284..f35c96a4fe3 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/PsiMethodCall.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/PsiMethodCall.java @@ -18,12 +18,12 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.*; import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor; import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -39,9 +39,12 @@ public class PsiMethodCall implements IntrinsicMethod { } @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, - List arguments, StackValue receiver, @NotNull GenerationState state) { - final CallableMethod callableMethod = state.getInjector().getJetTypeMapper().mapToCallableMethod(method, false, OwnerKind.IMPLEMENTATION); + public StackValue generate( + ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, + List arguments, StackValue receiver, @NotNull GenerationState state + ) { + final CallableMethod callableMethod = + state.getInjector().getJetTypeMapper().mapToCallableMethod(method, false, OwnerKind.IMPLEMENTATION); codegen.invokeMethodWithArguments(callableMethod, (JetCallExpression) element, receiver); return StackValue.onStack(callableMethod.getSignature().getAsmMethod().getReturnType()); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/RangeTo.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/RangeTo.java index f145a0a976f..7d67a8026c0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/RangeTo.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/RangeTo.java @@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetBinaryExpression; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -38,28 +38,38 @@ public class RangeTo implements IntrinsicMethod { } @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { - if (arguments.size()==1) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { + if (arguments.size() == 1) { final Type leftType = receiver.type; final Type rightType = codegen.expressionType(arguments.get(0)); receiver.put(Type.INT_TYPE, v); codegen.gen(arguments.get(0), rightType); - v.invokestatic("jet/runtime/Ranges", "rangeTo", "(" + receiver.type.getDescriptor() + leftType.getDescriptor() + ")" + expectedType.getDescriptor()); + v.invokestatic("jet/runtime/Ranges", "rangeTo", + "(" + receiver.type.getDescriptor() + leftType.getDescriptor() + ")" + expectedType.getDescriptor()); return StackValue.onStack(expectedType); } else { JetBinaryExpression expression = (JetBinaryExpression) element; final Type leftType = codegen.expressionType(expression.getLeft()); final Type rightType = codegen.expressionType(expression.getRight()); -// if (JetTypeMapper.isIntPrimitive(leftType)) { - codegen.gen(expression.getLeft(), leftType); - codegen.gen(expression.getRight(), rightType); - v.invokestatic("jet/runtime/Ranges", "rangeTo", "(" + leftType.getDescriptor() + rightType.getDescriptor() + ")" + expectedType.getDescriptor()); - return StackValue.onStack(expectedType); -// } -// else { -// throw new UnsupportedOperationException("ranges are only supported for int objects"); -// } + // if (JetTypeMapper.isIntPrimitive(leftType)) { + codegen.gen(expression.getLeft(), leftType); + codegen.gen(expression.getRight(), rightType); + v.invokestatic("jet/runtime/Ranges", "rangeTo", + "(" + leftType.getDescriptor() + rightType.getDescriptor() + ")" + expectedType.getDescriptor()); + return StackValue.onStack(expectedType); + // } + // else { + // throw new UnsupportedOperationException("ranges are only supported for int objects"); + // } } } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/StringGetChar.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/StringGetChar.java index b9186862567..d0d3874bf4c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/StringGetChar.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/StringGetChar.java @@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -33,11 +33,21 @@ import java.util.List; */ public class StringGetChar implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { - if (receiver != null) + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { + if (receiver != null) { receiver.put(JetTypeMapper.TYPE_OBJECT, v); - if (arguments != null) + } + if (arguments != null) { codegen.gen(arguments.get(0)).put(Type.INT_TYPE, v); + } v.invokeinterface("java/lang/CharSequence", "charAt", "(I)C"); return StackValue.onStack(Type.CHAR_TYPE); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/StringLength.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/StringLength.java index 27d692394c9..a7183c4ea33 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/StringLength.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/StringLength.java @@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -33,7 +33,15 @@ import java.util.List; */ public class StringLength implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { receiver.put(JetTypeMapper.TYPE_OBJECT, v); v.invokeinterface("java/lang/CharSequence", "length", "()I"); return StackValue.onStack(Type.INT_TYPE); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/StringPlus.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/StringPlus.java index f1b00b5b3d7..c889a930598 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/StringPlus.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/StringPlus.java @@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -33,7 +33,15 @@ import java.util.List; */ public class StringPlus implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { if (receiver == null || receiver == StackValue.none()) { codegen.gen(arguments.get(0)).put(JetTypeMapper.JL_STRING_TYPE, v); codegen.gen(arguments.get(1)).put(JetTypeMapper.TYPE_OBJECT, v); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/StupidSync.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/StupidSync.java index a75aefb03c0..618543e6645 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/StupidSync.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/StupidSync.java @@ -19,22 +19,30 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.Arrays; import java.util.List; public class StupidSync implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, @Nullable List arguments, StackValue receiver, @NotNull GenerationState state) { - codegen.pushMethodArguments((JetCallExpression)element, Arrays.asList(JetTypeMapper.TYPE_OBJECT, JetTypeMapper.TYPE_FUNCTION0)); + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + @Nullable PsiElement element, + @Nullable List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { + codegen.pushMethodArguments((JetCallExpression) element, Arrays.asList(JetTypeMapper.TYPE_OBJECT, JetTypeMapper.TYPE_FUNCTION0)); v.invokestatic("jet/runtime/Intrinsics", "stupidSync", "(Ljava/lang/Object;Ljet/Function0;)Ljava/lang/Object;"); StackValue.onStack(JetTypeMapper.TYPE_OBJECT).put(expectedType, v); return StackValue.onStack(expectedType); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Sure.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Sure.java index 9096016b0cd..6bb41851632 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Sure.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Sure.java @@ -18,6 +18,9 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Label; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.StackValue; @@ -26,9 +29,6 @@ import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; -import org.jetbrains.asm4.Label; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -37,11 +37,20 @@ import java.util.List; */ public class Sure implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { JetCallExpression call = (JetCallExpression) element; - ResolvedCall resolvedCall = codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression()); + ResolvedCall resolvedCall = + codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression()); assert resolvedCall != null; - if (resolvedCall.getReceiverArgument().getType().isNullable()) { + if (resolvedCall.getReceiverArgument().getType().isNullable()) { receiver.put(receiver.type, v); v.dup(); Label ok = new Label(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ToString.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ToString.java index 4692b744952..34b1507b674 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ToString.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ToString.java @@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -33,7 +33,15 @@ import java.util.List; */ public class ToString implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { receiver.put(JetTypeMapper.TYPE_OBJECT, v); v.invokestatic("java/lang/String", "valueOf", "(Ljava/lang/Object;)Ljava/lang/String;"); return StackValue.onStack(JetTypeMapper.JL_STRING_TYPE); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryMinus.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryMinus.java index eeb74da8dad..56038c8ec2a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryMinus.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryMinus.java @@ -18,13 +18,13 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -33,7 +33,15 @@ import java.util.List; */ public class UnaryMinus implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element, List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { boolean nullable = expectedType.getSort() == Type.OBJECT; if (nullable) { expectedType = JetTypeMapper.unboxType(expectedType); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryPlus.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryPlus.java index 7ea5339f4d4..fc603142d19 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryPlus.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryPlus.java @@ -19,13 +19,13 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import java.util.List; @@ -34,13 +34,22 @@ import java.util.List; */ public class UnaryPlus implements IntrinsicMethod { @Override - public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, @Nullable List arguments, StackValue receiver, @NotNull GenerationState state) { + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + @Nullable PsiElement element, + @Nullable List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { boolean nullable = expectedType.getSort() == Type.OBJECT; if (nullable) { expectedType = JetTypeMapper.unboxType(expectedType); } - if (receiver != null && receiver != StackValue.none()) + if (receiver != null && receiver != StackValue.none()) { receiver.put(expectedType, v); + } else { assert arguments != null; codegen.gen(arguments.get(0), expectedType); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/signature/BothSignatureWriter.java b/compiler/backend/src/org/jetbrains/jet/codegen/signature/BothSignatureWriter.java index 2496183bb99..0e56775152f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/signature/BothSignatureWriter.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/signature/BothSignatureWriter.java @@ -18,10 +18,12 @@ package org.jetbrains.jet.codegen.signature; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.Method; +import org.jetbrains.asm4.signature.SignatureVisitor; +import org.jetbrains.asm4.signature.SignatureWriter; +import org.jetbrains.asm4.util.CheckSignatureAdapter; import org.jetbrains.jet.codegen.JetTypeMapper; -import org.jetbrains.jet.codegen.signature.JvmMethodParameterKind; -import org.jetbrains.jet.codegen.signature.JvmMethodParameterSignature; -import org.jetbrains.jet.codegen.signature.JvmMethodSignature; import org.jetbrains.jet.lang.resolve.java.JetSignatureUtils; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.Variance; @@ -29,11 +31,6 @@ import org.jetbrains.jet.rt.signature.JetSignatureAdapter; import org.jetbrains.jet.rt.signature.JetSignatureReader; import org.jetbrains.jet.rt.signature.JetSignatureVariance; import org.jetbrains.jet.rt.signature.JetSignatureWriter; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.Method; -import org.jetbrains.asm4.signature.SignatureVisitor; -import org.jetbrains.asm4.signature.SignatureWriter; -import org.jetbrains.asm4.util.CheckSignatureAdapter; import java.util.ArrayList; import java.util.List; @@ -48,9 +45,8 @@ public class BothSignatureWriter { public enum Mode { METHOD(CheckSignatureAdapter.METHOD_SIGNATURE), - CLASS(CheckSignatureAdapter.CLASS_SIGNATURE), - ; - + CLASS(CheckSignatureAdapter.CLASS_SIGNATURE),; + private final int asmType; Mode(int asmType) { @@ -70,18 +66,18 @@ public class BothSignatureWriter { SUPERS, CLASS_END, } - + private final SignatureWriter signatureWriter = new SignatureWriter(); private final SignatureVisitor signatureVisitor; private JetSignatureWriter jetSignatureWriter; - + private String kotlinClassParameters; private String kotlinClassSignature; - + private List kotlinParameterTypes = new ArrayList(); private String kotlinReturnType; - + private int jvmCurrentTypeArrayLevel; private Type jvmCurrentType; private Type jvmReturnType; @@ -119,11 +115,10 @@ public class BothSignatureWriter { } - private SignatureVisitor signatureVisitor() { return !visitors.isEmpty() ? visitors.peek() : signatureVisitor; } - + private void checkTopLevel() { if (DEBUG_SIGNATURE_WRITER) { if (!visitors.isEmpty()) { @@ -131,7 +126,7 @@ public class BothSignatureWriter { } } } - + private void checkMode(Mode mode) { if (DEBUG_SIGNATURE_WRITER) { if (mode != this.mode) { @@ -139,7 +134,7 @@ public class BothSignatureWriter { } } } - + private void checkState(State state) { if (DEBUG_SIGNATURE_WRITER) { if (state != this.state) { @@ -151,7 +146,7 @@ public class BothSignatureWriter { checkTopLevel(); } } - + private void transitionState(State from, State to) { checkState(from); state = to; @@ -207,7 +202,7 @@ public class BothSignatureWriter { writeAsmType0(Type.VOID_TYPE); } } - + private String makeArrayPrefix() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < jvmCurrentTypeArrayLevel; ++i) { @@ -215,7 +210,7 @@ public class BothSignatureWriter { } return sb.toString(); } - + private void writeAsmType0(Type type) { if (jvmCurrentType == null) { jvmCurrentType = Type.getType(makeArrayPrefix() + type.getDescriptor()); @@ -240,17 +235,21 @@ public class BothSignatureWriter { ++jvmCurrentTypeArrayLevel; } } - + public void writeArrayEnd() { pop(); } - + private static JetSignatureVariance toJetSignatureVariance(Variance variance) { switch (variance) { - case INVARIANT: return JetSignatureVariance.INVARIANT; - case IN_VARIANCE: return JetSignatureVariance.IN; - case OUT_VARIANCE: return JetSignatureVariance.OUT; - default: throw new IllegalStateException(); + case INVARIANT: + return JetSignatureVariance.INVARIANT; + case IN_VARIANCE: + return JetSignatureVariance.IN; + case OUT_VARIANCE: + return JetSignatureVariance.OUT; + default: + throw new IllegalStateException(); } } @@ -260,7 +259,7 @@ public class BothSignatureWriter { jetSignatureWriter.visitTypeArgument(jsVariance); generic = true; } - + public void writeTypeArgumentEnd() { pop(); } @@ -280,7 +279,7 @@ public class BothSignatureWriter { generic = true; } - + public void writeFormalTypeParameterEnd() { jetSignatureWriter.visitFormalTypeParameterEnd(); } @@ -309,7 +308,7 @@ public class BothSignatureWriter { push(signatureVisitor().visitClassBound()); jetSignatureWriter.visitClassBound(); } - + public void writeClassBoundEnd() { pop(); } @@ -322,7 +321,7 @@ public class BothSignatureWriter { public void writeInterfaceBoundEnd() { pop(); } - + public void writeParametersStart() { transitionState(State.TYPE_PARAMETERS, State.PARAMETERS); @@ -351,7 +350,7 @@ public class BothSignatureWriter { //jetSignatureWriter.visitParameterType(); } - + public void writeParameterTypeEnd() { pop(); @@ -386,10 +385,10 @@ public class BothSignatureWriter { push(signatureVisitor().visitReturnType()); //jetSignatureWriter.visitReturnType(); } - + public void writeReturnTypeEnd() { pop(); - + kotlinReturnType = jetSignatureWriter.toString(); if (jvmCurrentType == null) { @@ -407,13 +406,13 @@ public class BothSignatureWriter { jetSignatureWriter = null; transitionState(State.RETURN_TYPE, State.METHOD_END); } - + public void writeVoidReturn() { writeReturnType(); writeAsmType(Type.VOID_TYPE, false); writeReturnTypeEnd(); } - + public void writeSupersStart() { transitionState(State.TYPE_PARAMETERS, State.SUPERS); jetSignatureWriter = new JetSignatureWriter(); @@ -434,7 +433,7 @@ public class BothSignatureWriter { push(signatureVisitor().visitSuperclass()); jetSignatureWriter.visitSuperclass(); } - + public void writeSuperclassEnd() { pop(); if (!visitors.isEmpty()) { @@ -458,7 +457,6 @@ public class BothSignatureWriter { } - @NotNull public Method makeAsmMethod(String name) { List jvmParameterTypes = new ArrayList(kotlinParameterTypes.size()); @@ -476,7 +474,7 @@ public class BothSignatureWriter { checkTopLevel(); return generic ? signatureWriter.toString() : null; } - + @NotNull public List makeKotlinParameterTypes() { checkState(State.METHOD_END); @@ -489,7 +487,7 @@ public class BothSignatureWriter { checkState(State.METHOD_END); return kotlinReturnType; } - + public String makeKotlinMethodTypeParameters() { checkState(State.METHOD_END); return kotlinClassParameters; @@ -522,5 +520,4 @@ public class BothSignatureWriter { return new JvmMethodSignature(makeAsmMethod(name), makeKotlinParameterTypes()); } } - } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/signature/JvmClassSignature.java b/compiler/backend/src/org/jetbrains/jet/codegen/signature/JvmClassSignature.java index 4ae060bc596..10860797ae6 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/signature/JvmClassSignature.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/signature/JvmClassSignature.java @@ -30,8 +30,10 @@ public class JvmClassSignature { private final String javaGenericSignature; private final String kotlinGenericSignature; - public JvmClassSignature(String name, String superclassName, List interfaces, - @Nullable String javaGenericSignature, @Nullable String kotlinGenericSignature) { + public JvmClassSignature( + String name, String superclassName, List interfaces, + @Nullable String javaGenericSignature, @Nullable String kotlinGenericSignature + ) { this.name = name; this.superclassName = superclassName; this.interfaces = interfaces; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/signature/JvmMethodParameterKind.java b/compiler/backend/src/org/jetbrains/jet/codegen/signature/JvmMethodParameterKind.java index a1c6a82c467..4121da62911 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/signature/JvmMethodParameterKind.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/signature/JvmMethodParameterKind.java @@ -16,8 +16,6 @@ package org.jetbrains.jet.codegen.signature; -import org.jetbrains.jet.lang.descriptors.ClassDescriptor; - /** * @author Stepan Koltsov */ diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/signature/JvmMethodParameterSignature.java b/compiler/backend/src/org/jetbrains/jet/codegen/signature/JvmMethodParameterSignature.java index f3cda539208..3e973dcf512 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/signature/JvmMethodParameterSignature.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/signature/JvmMethodParameterSignature.java @@ -31,7 +31,8 @@ public class JvmMethodParameterSignature { private final JvmMethodParameterKind kind; public JvmMethodParameterSignature( - @NotNull Type asmType, @NotNull String kotlinSignature, @NotNull JvmMethodParameterKind kind) { + @NotNull Type asmType, @NotNull String kotlinSignature, @NotNull JvmMethodParameterKind kind + ) { this.asmType = asmType; this.kotlinSignature = kotlinSignature; this.kind = kind; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/signature/JvmMethodSignature.java b/compiler/backend/src/org/jetbrains/jet/codegen/signature/JvmMethodSignature.java index 4c59ce65be8..440a45bad5b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/signature/JvmMethodSignature.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/signature/JvmMethodSignature.java @@ -31,7 +31,9 @@ public class JvmMethodSignature { @NotNull private final Method asmMethod; - /** Null when we don't care about type parameters */ + /** + * Null when we don't care about type parameters + */ private final String genericsSignature; private final String kotlinTypeParameter; @NotNull @@ -44,8 +46,13 @@ public class JvmMethodSignature { */ private final boolean genericsAvailable; - public JvmMethodSignature(@NotNull Method asmMethod, @Nullable String genericsSignature, - @Nullable String kotlinTypeParameters, @NotNull List kotlinParameterTypes, @NotNull String kotlinReturnType) { + public JvmMethodSignature( + @NotNull Method asmMethod, + @Nullable String genericsSignature, + @Nullable String kotlinTypeParameters, + @NotNull List kotlinParameterTypes, + @NotNull String kotlinReturnType + ) { this.asmMethod = asmMethod; this.genericsSignature = genericsSignature; this.kotlinTypeParameter = kotlinTypeParameters; @@ -53,7 +60,7 @@ public class JvmMethodSignature { this.kotlinReturnType = kotlinReturnType; this.genericsAvailable = true; } - + public JvmMethodSignature(@NotNull Method asmMethod, @NotNull List kotlinParameterTypes) { this.asmMethod = asmMethod; this.genericsSignature = null; @@ -62,11 +69,16 @@ public class JvmMethodSignature { this.kotlinReturnType = ""; this.genericsAvailable = false; } - - public static JvmMethodSignature simple(@NotNull String methodName, @NotNull Type returnType, @NotNull List parameterSignatures) { - return new JvmMethodSignature(new Method(methodName, returnType, getTypes(parameterSignatures).toArray(new Type[0])), parameterSignatures); + + public static JvmMethodSignature simple( + @NotNull String methodName, + @NotNull Type returnType, + @NotNull List parameterSignatures + ) { + return new JvmMethodSignature(new Method(methodName, returnType, getTypes(parameterSignatures).toArray(new Type[0])), + parameterSignatures); } - + @NotNull private static List getTypes(@NotNull List signatures) { List r = new ArrayList(signatures.size()); @@ -103,12 +115,12 @@ public class JvmMethodSignature { checkGenericsAvailable(); return kotlinParameterTypes; } - + public int getParameterCount() { // TODO: slow return asmMethod.getArgumentTypes().length; } - + @NotNull public String getKotlinParameterType(int i) { checkGenericsAvailable(); @@ -125,7 +137,7 @@ public class JvmMethodSignature { checkGenericsAvailable(); return kotlinReturnType; } - + public List getValueParameterTypes() { List r = new ArrayList(kotlinParameterTypes.size()); for (JvmMethodParameterSignature p : kotlinParameterTypes) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/signature/JvmPropertyAccessorSignature.java b/compiler/backend/src/org/jetbrains/jet/codegen/signature/JvmPropertyAccessorSignature.java index f5da2e1cb5b..da2054c3084 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/signature/JvmPropertyAccessorSignature.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/signature/JvmPropertyAccessorSignature.java @@ -17,7 +17,6 @@ package org.jetbrains.jet.codegen.signature; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.codegen.signature.JvmMethodSignature; /** * @author Stepan Koltsov diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/signature/kotlin/JetMethodAnnotationWriter.java b/compiler/backend/src/org/jetbrains/jet/codegen/signature/kotlin/JetMethodAnnotationWriter.java index 25607f52c86..3ceba45f16d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/signature/kotlin/JetMethodAnnotationWriter.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/signature/kotlin/JetMethodAnnotationWriter.java @@ -17,10 +17,10 @@ package org.jetbrains.jet.codegen.signature.kotlin; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; -import org.jetbrains.jet.utils.BitSetUtils; import org.jetbrains.asm4.AnnotationVisitor; import org.jetbrains.asm4.MethodVisitor; +import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; +import org.jetbrains.jet.utils.BitSetUtils; import java.util.BitSet; @@ -58,13 +58,13 @@ public class JetMethodAnnotationWriter { av.visit(JvmStdlibNames.JET_METHOD_PROPERTY_TYPE_FIELD, propertyType); } } - + public void writeNullableReturnType(boolean nullableReturnType) { if (nullableReturnType) { av.visit(JvmStdlibNames.JET_METHOD_NULLABLE_RETURN_TYPE_FIELD, nullableReturnType); } } - + public void visitEnd() { av.visitEnd(); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/signature/kotlin/JetValueParameterAnnotationWriter.java b/compiler/backend/src/org/jetbrains/jet/codegen/signature/kotlin/JetValueParameterAnnotationWriter.java index a4552375595..da343bd3aae 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/signature/kotlin/JetValueParameterAnnotationWriter.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/signature/kotlin/JetValueParameterAnnotationWriter.java @@ -17,9 +17,9 @@ package org.jetbrains.jet.codegen.signature.kotlin; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.asm4.AnnotationVisitor; import org.jetbrains.asm4.MethodVisitor; +import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; /** * @author Stepan Koltsov From ee5f5988364a8dd6adb883b7ea40d880235f4d7d Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 15 Aug 2012 18:11:08 +0400 Subject: [PATCH 33/36] Wrong test data fixed (previously commited by mistake) --- .../diagnostics/tests/Delegation_ScopeInitializationOrder.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/testData/diagnostics/tests/Delegation_ScopeInitializationOrder.kt b/compiler/testData/diagnostics/tests/Delegation_ScopeInitializationOrder.kt index d1e51af531a..d4255d31081 100644 --- a/compiler/testData/diagnostics/tests/Delegation_ScopeInitializationOrder.kt +++ b/compiler/testData/diagnostics/tests/Delegation_ScopeInitializationOrder.kt @@ -1,4 +1,3 @@ -class D(b: B) : C(b) trait A { fun foo() {} } From 1fe28802aa6dba57baa199430e42c0433d86be0d Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 15 Aug 2012 18:25:16 +0400 Subject: [PATCH 34/36] Increase minimum version for required IDEA to next EAP as trunk is not compatible with 120.305 anymore --- idea/src/META-INF/plugin.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 011d013326a..d0dc9dcf748 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -6,7 +6,7 @@ @snapshot@ JetBrains Inc. - + JUnit From ca615aac3d241ebccc7c33b6bccc6aba854bcf0d Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Wed, 15 Aug 2012 20:25:35 +0300 Subject: [PATCH 35/36] KT-2350 fix: enums with overrides and constructor parameters --- .../jetbrains/jet/codegen/ImplementationBodyCodegen.java | 3 +-- compiler/testData/codegen/regressions/kt2350.kt | 7 +++++++ compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java | 5 +++++ 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/codegen/regressions/kt2350.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index ce9fc75dc0d..368e9c68974 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -1088,7 +1088,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.dup(); iv.iconst(ordinal); - // TODO type and constructor parameters ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, enumConstant); String implClass = typeMapper.mapType(classDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName(); @@ -1103,7 +1102,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.aconst(enumConstant.getName()); iv.iconst(ordinal); - if (delegationSpecifiers.size() == 1) { + if (delegationSpecifiers.size() == 1 && !state.getInjector().getClosureAnnotator().enumEntryNeedSubclass(enumConstant)) { final JetDelegationSpecifier specifier = delegationSpecifiers.get(0); if (specifier instanceof JetDelegatorToSuperCall) { final JetDelegatorToSuperCall superCall = (JetDelegatorToSuperCall) specifier; diff --git a/compiler/testData/codegen/regressions/kt2350.kt b/compiler/testData/codegen/regressions/kt2350.kt new file mode 100644 index 00000000000..b32bbb58e9b --- /dev/null +++ b/compiler/testData/codegen/regressions/kt2350.kt @@ -0,0 +1,7 @@ +enum class A(val b: String) { + E1: A("OK"){ override fun t() = b } + + abstract fun t(): String +} + +fun box()= A.E1.t() diff --git a/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java index c57ea2dae7a..1aa3990052c 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java @@ -135,4 +135,9 @@ public class EnumGenTest extends CodegenTestCase { public void testKt1119() { blackBoxFile("regressions/kt1119.kt"); } + + public void testKt2350() { + blackBoxFile("regressions/kt2350.kt"); + System.out.println(generateToText()); + } } From 0b054f224c06611a6c3e6a6947ef2c7fd425ca2d Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 15 Aug 2012 19:16:57 +0400 Subject: [PATCH 36/36] "open" in final class is a warning now --- .../src/org/jetbrains/jet/lang/diagnostics/Errors.java | 4 +--- .../jet/lang/diagnostics/rendering/DefaultErrorMessages.java | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java index c4ad2473e0a..7b57957f861 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java @@ -17,7 +17,6 @@ package org.jetbrains.jet.lang.diagnostics; import com.google.common.collect.Lists; -import com.google.common.collect.Sets; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiNameIdentifierOwner; @@ -34,7 +33,6 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Collection; import java.util.List; -import java.util.Set; import static org.jetbrains.jet.lang.diagnostics.PositioningStrategies.*; import static org.jetbrains.jet.lang.diagnostics.Severity.ERROR; @@ -121,7 +119,7 @@ public interface Errors { DiagnosticFactory1 NON_MEMBER_ABSTRACT_FUNCTION = DiagnosticFactory1.create(ERROR, ABSTRACT_MODIFIER); DiagnosticFactory1 NON_MEMBER_FUNCTION_NO_BODY = DiagnosticFactory1.create(ERROR, NAMED_ELEMENT); - SimpleDiagnosticFactory NON_FINAL_MEMBER_IN_FINAL_CLASS = SimpleDiagnosticFactory.create(ERROR, positionModifier(JetTokens.OPEN_KEYWORD)); + SimpleDiagnosticFactory NON_FINAL_MEMBER_IN_FINAL_CLASS = SimpleDiagnosticFactory.create(WARNING, positionModifier(JetTokens.OPEN_KEYWORD)); SimpleDiagnosticFactory PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE = SimpleDiagnosticFactory.create(ERROR, NAMED_ELEMENT); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java index 2ebdebf0349..91e1a70d363 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java @@ -134,7 +134,7 @@ public class DefaultErrorMessages { MAP.put(NON_MEMBER_ABSTRACT_FUNCTION, "Function ''{0}'' is not a class or trait member and cannot be abstract", NAME); MAP.put(NON_MEMBER_FUNCTION_NO_BODY, "Function ''{0}'' must have a body", NAME); - MAP.put(NON_FINAL_MEMBER_IN_FINAL_CLASS, "Non-final member in a final class"); + MAP.put(NON_FINAL_MEMBER_IN_FINAL_CLASS, "\"open\" has no effect in a final class"); MAP.put(PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE, "Public or protected member should have specified type");