diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java index bc28636916b..48da0a24027 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java @@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import java.util.Collection; @@ -56,7 +57,7 @@ public class JavaClassMembersScope extends JavaClassOrPackageScope { @NotNull @Override - public Collection getDeclarationsByLabel(String labelName) { + public Collection getDeclarationsByLabel(LabelName labelName) { throw new UnsupportedOperationException(); // TODO } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java index d03bc26759f..0396863563a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AbstractScopeAdapter.java @@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; @@ -91,7 +92,7 @@ public abstract class AbstractScopeAdapter implements JetScope { @NotNull @Override - public Collection getDeclarationsByLabel(String labelName) { + public Collection getDeclarationsByLabel(LabelName labelName) { return getWorkerScope().getDeclarationsByLabel(labelName); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/name/LabelName.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/name/LabelName.java new file mode 100644 index 00000000000..01cc6ff234a --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/name/LabelName.java @@ -0,0 +1,68 @@ +/* + * 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.name; + +import org.jetbrains.annotations.NotNull; + +/** + * @author Stepan Koltsov + */ +public class LabelName { + + @NotNull + private final String name; + + public LabelName(@NotNull String name) { + if (name.startsWith("@")) { + // label may contain @, and may not contain + //throw new IllegalArgumentException("@ must be chopped: " + name); + } + + if (name.length() == 0) { + // label can be empty + //throw new IllegalStateException("label cannot be empty"); + } + + this.name = name; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return name; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + LabelName name1 = (LabelName) o; + + if (!name.equals(name1.name)) return false; + + return true; + } + + @Override + public int hashCode() { + return name.hashCode(); + } +} 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 50cf7445629..dbb8dbe282b 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 @@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve.scopes; import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import java.util.Collection; @@ -134,7 +135,7 @@ public class ChainedScope implements JetScope { @NotNull @Override - public Collection getDeclarationsByLabel(String labelName) { + public Collection getDeclarationsByLabel(LabelName labelName) { for (JetScope jetScope : scopeChain) { Collection declarationsByLabel = jetScope.getDeclarationsByLabel(labelName); if (!declarationsByLabel.isEmpty()) return declarationsByLabel; // TODO : merge? diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/InnerClassesScopeWrapper.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/InnerClassesScopeWrapper.java index 4867b747fdc..97c7306b733 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/InnerClassesScopeWrapper.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/InnerClassesScopeWrapper.java @@ -24,6 +24,7 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassKind; import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import java.util.Collection; @@ -58,7 +59,7 @@ public class InnerClassesScopeWrapper extends JetScopeImpl { @NotNull @Override - public Collection getDeclarationsByLabel(String labelName) { + public Collection getDeclarationsByLabel(LabelName labelName) { Collection declarationsByLabel = actualScope.getDeclarationsByLabel(labelName); return Collections2.filter(declarationsByLabel, new Predicate() { @Override diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java index 9f919dd34f4..e878da02843 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java @@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve.scopes; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import java.util.Collection; @@ -67,7 +68,7 @@ public interface JetScope { DeclarationDescriptor getContainingDeclaration(); @NotNull - Collection getDeclarationsByLabel(String labelName); + Collection getDeclarationsByLabel(LabelName labelName); /** * @param fieldName includes the "$" diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeImpl.java index 7c8d03fe352..268d700bbe4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeImpl.java @@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve.scopes; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import java.util.Collection; @@ -75,7 +76,7 @@ public abstract class JetScopeImpl implements JetScope { @NotNull @Override - public Collection getDeclarationsByLabel(String labelName) { + public Collection getDeclarationsByLabel(LabelName labelName) { return Collections.emptyList(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java index bed37d160a0..7a27650d170 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java @@ -21,6 +21,7 @@ import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.TypeSubstitutor; @@ -136,7 +137,7 @@ public class SubstitutingScope implements JetScope { @NotNull @Override - public Collection getDeclarationsByLabel(String labelName) { + public Collection getDeclarationsByLabel(LabelName labelName) { throw new UnsupportedOperationException(); // TODO } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java index cc871527ce7..cfd8545c75b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java @@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.util.CommonSuppliers; @@ -56,7 +57,7 @@ public class WritableScopeImpl extends WritableScopeWithImports { private Map namespaceAliases; @Nullable - private Map> labelsToDescriptors; + private Map> labelsToDescriptors; @Nullable private Map objectDescriptors; @@ -137,9 +138,9 @@ public class WritableScopeImpl extends WritableScopeWithImports { } @NotNull - private Map> getLabelsToDescriptors() { + private Map> getLabelsToDescriptors() { if (labelsToDescriptors == null) { - labelsToDescriptors = new HashMap>(); + labelsToDescriptors = new HashMap>(); } return labelsToDescriptors; } @@ -154,11 +155,11 @@ public class WritableScopeImpl extends WritableScopeWithImports { @NotNull @Override - public Collection getDeclarationsByLabel(@NotNull String labelName) { + public Collection getDeclarationsByLabel(@NotNull LabelName labelName) { checkMayRead(); Collection superResult = super.getDeclarationsByLabel(labelName); - Map> labelsToDescriptors = getLabelsToDescriptors(); + Map> labelsToDescriptors = getLabelsToDescriptors(); List declarationDescriptors = labelsToDescriptors.get(labelName); if (declarationDescriptors == null) { return superResult; @@ -173,9 +174,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { public void addLabeledDeclaration(@NotNull DeclarationDescriptor descriptor) { checkMayWrite(); - Map> labelsToDescriptors = getLabelsToDescriptors(); - String name = descriptor.getName(); - assert name != null; + Map> labelsToDescriptors = getLabelsToDescriptors(); + LabelName name = new LabelName(descriptor.getName()); List declarationDescriptors = labelsToDescriptors.get(name); if (declarationDescriptors == null) { declarationDescriptors = new ArrayList(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java index 08380c75cbb..231564b10bc 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java @@ -22,6 +22,7 @@ import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import java.util.Collection; @@ -49,7 +50,7 @@ public class WriteThroughScope extends WritableScopeWithImports { @Override @NotNull - public Collection getDeclarationsByLabel(String labelName) { + public Collection getDeclarationsByLabel(LabelName labelName) { checkMayRead(); return writableWorker.getDeclarationsByLabel(labelName); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java index bbcef8906f7..29e22f54240 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java @@ -20,6 +20,7 @@ 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.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.error.ErrorSimpleFunctionDescriptorImpl; @@ -99,7 +100,7 @@ public class ErrorUtils { @NotNull @Override - public Collection getDeclarationsByLabel(String labelName) { + public Collection getDeclarationsByLabel(LabelName labelName) { return Collections.emptyList(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index fe620c7beda..71b0589107f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -36,6 +36,7 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValueFactory; import org.jetbrains.jet.lang.resolve.constants.*; import org.jetbrains.jet.lang.resolve.constants.StringValue; +import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver; @@ -486,7 +487,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { ReceiverDescriptor thisReceiver = null; String labelName = expression.getLabelName(); if (labelName != null) { - thisReceiver = context.labelResolver.resolveThisLabel(expression.getInstanceReference(), expression.getTargetLabel(), context, thisReceiver, labelName); + thisReceiver = context.labelResolver.resolveThisLabel( + expression.getInstanceReference(), expression.getTargetLabel(), context, thisReceiver, new LabelName(labelName)); } else { if (onlyClassReceivers) { @@ -682,7 +684,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { if (JetTokens.LABELS.contains(operationSign.getReferencedNameElementType())) { String referencedName = operationSign.getReferencedName(); referencedName = referencedName == null ? " " : referencedName; - context.labelResolver.enterLabeledElement(referencedName.substring(1), baseExpression); + context.labelResolver.enterLabeledElement(new LabelName(referencedName.substring(1)), baseExpression); // TODO : Some processing for the label? JetType type = facade.getType(baseExpression, context, isStatement); context.labelResolver.exitLabeledElement(baseExpression); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/LabelResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/LabelResolver.java index 6f24fd78619..afcad02ef36 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/LabelResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/LabelResolver.java @@ -25,6 +25,7 @@ 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.BindingContextUtils; +import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import java.util.*; @@ -37,11 +38,11 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.*; */ public class LabelResolver { - private final Map> labeledElements = new HashMap>(); + private final Map> labeledElements = new HashMap>(); public LabelResolver() {} - public void enterLabeledElement(@NotNull String labelName, @NotNull JetExpression labeledExpression) { + public void enterLabeledElement(@NotNull LabelName labelName, @NotNull JetExpression labeledExpression) { JetExpression deparenthesized = JetPsiUtil.deparenthesize(labeledExpression); if (deparenthesized != null) { Stack stack = labeledElements.get(labelName); @@ -56,8 +57,8 @@ public class LabelResolver { public void exitLabeledElement(@NotNull JetExpression expression) { JetExpression deparenthesized = JetPsiUtil.deparenthesize(expression); // TODO : really suboptimal - for (Iterator>> mapIter = labeledElements.entrySet().iterator(); mapIter.hasNext(); ) { - Map.Entry> entry = mapIter.next(); + for (Iterator>> mapIter = labeledElements.entrySet().iterator(); mapIter.hasNext(); ) { + Map.Entry> entry = mapIter.next(); Stack stack = entry.getValue(); for (Iterator stackIter = stack.iterator(); stackIter.hasNext(); ) { JetElement recorded = stackIter.next(); @@ -72,7 +73,7 @@ public class LabelResolver { } @Nullable - private JetElement resolveControlLabel(@NotNull String labelName, @NotNull JetSimpleNameExpression labelExpression, boolean reportUnresolved, ExpressionTypingContext context) { + private JetElement resolveControlLabel(@NotNull LabelName labelName, @NotNull JetSimpleNameExpression labelExpression, boolean reportUnresolved, ExpressionTypingContext context) { Collection declarationsByLabel = context.scope.getDeclarationsByLabel(labelName); int size = declarationsByLabel.size(); @@ -99,14 +100,13 @@ public class LabelResolver { public JetElement resolveLabel(JetLabelQualifiedExpression expression, ExpressionTypingContext context) { JetSimpleNameExpression labelElement = expression.getTargetLabel(); if (labelElement != null) { - String labelName = expression.getLabelName(); - assert labelName != null; + LabelName labelName = new LabelName(expression.getLabelName()); return resolveControlLabel(labelName, labelElement, true, context); } return null; } - private JetElement resolveNamedLabel(@NotNull String labelName, @NotNull JetSimpleNameExpression labelExpression, boolean reportUnresolved, ExpressionTypingContext context) { + private JetElement resolveNamedLabel(@NotNull LabelName labelName, @NotNull JetSimpleNameExpression labelExpression, boolean reportUnresolved, ExpressionTypingContext context) { Stack stack = labeledElements.get(labelName); if (stack == null || stack.isEmpty()) { if (reportUnresolved) { @@ -123,7 +123,8 @@ public class LabelResolver { return result; } - public ReceiverDescriptor resolveThisLabel(JetReferenceExpression thisReference, JetSimpleNameExpression targetLabel, ExpressionTypingContext context, ReceiverDescriptor thisReceiver, String labelName) { + public ReceiverDescriptor resolveThisLabel(JetReferenceExpression thisReference, JetSimpleNameExpression targetLabel, + ExpressionTypingContext context, ReceiverDescriptor thisReceiver, LabelName labelName) { Collection declarationsByLabel = context.scope.getDeclarationsByLabel(labelName); int size = declarationsByLabel.size(); assert targetLabel != null;