Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Trofimov
2013-11-25 19:19:47 +01:00
29 changed files with 400 additions and 39 deletions
+7
View File
@@ -299,6 +299,13 @@ public def layoutCommunityPlugins(String home) {
}
}
jar("artifact-resolver-m31.jar") {
module("maven-artifact-resolver-m31")
module("maven-artifact-resolver-m2") {
include(name: 'org/jetbrains/idea/maven/artifactResolver/common/*')
}
}
dir("maven3") {
fileset(dir: "$home/plugins/maven/maven3-server-impl/lib") {include(name: "*.jar")}
fileset(dir: "$home/plugins/maven/maven3-server-impl/lib/maven3/lib") {include(name: "*.jar")}
@@ -0,0 +1,11 @@
Compiling files:
src/package2/A.java
End of files
Cleaning output files:
out/production/AddClassHidingImportedClass/package2/B.class
out/production/AddClassHidingImportedClass/package3/C.class
End of files
Compiling files:
src/package2/B.java
src/package3/C.java
End of files
@@ -0,0 +1,7 @@
package package1;
public class A {
public static class D {
public final String s = new String("package1");
}
}
@@ -0,0 +1,7 @@
package package2;
public class A {
public static class D {
public final String s = new String("package2");
}
}
@@ -0,0 +1,6 @@
package package2;
import package1.*;
public class B extends A{
}
@@ -0,0 +1,14 @@
package package3;
import package2.B;
public class C {
public B.D p;
public String get() {
p = new B.D();
return p.s;
}
}
@@ -321,15 +321,17 @@ public class ClassRepr extends Proto {
}
public String getPackageName() {
return getPackageName(name);
final String strValue = myContext.getValue(name);
return strValue != null? getPackageName(strValue) : null;
}
public String getPackageName(final int s) {
return getPackageName(myContext.getValue(s));
public String getShortName() {
final String strValue = myContext.getValue(name);
return strValue != null? getShortName(strValue) : null;
}
@NotNull
public static String getPackageName(final String raw) {
public static String getPackageName(@NotNull final String raw) {
final int index = raw.lastIndexOf('/');
if (index == -1) {
@@ -339,6 +341,17 @@ public class ClassRepr extends Proto {
return raw.substring(0, index);
}
@NotNull
public static String getShortName(@NotNull final String fqName) {
final int index = fqName.lastIndexOf('/');
if (index == -1) {
return fqName;
}
return fqName.substring(index + 1);
}
@Nullable
public FieldRepr findField(final int name) {
for (FieldRepr f : myFields) {
@@ -45,6 +45,7 @@ public class Mappings {
private final static String CLASS_TO_SUBCLASSES = "classToSubclasses.tab";
private final static String CLASS_TO_CLASS = "classToClass.tab";
private final static String SHORT_NAMES = "shortNames.tab";
private final static String SOURCE_TO_CLASS = "sourceToClass.tab";
private final static String CLASS_TO_SOURCE = "classToSource.tab";
private static final IntInlineKeyDescriptor INT_KEY_DESCRIPTOR = new IntInlineKeyDescriptor();
@@ -65,6 +66,7 @@ public class Mappings {
private final TIntHashSet myChangedClasses;
private final THashSet<File> myChangedFiles;
private final Set<ClassRepr> myDeletedClasses;
private final Set<ClassRepr> myAddedClasses;
private final Object myLock;
private final File myRootDir;
@@ -83,6 +85,10 @@ public class Mappings {
private IntIntMultiMaplet myClassToClassDependency;
private ObjectObjectMultiMaplet<File, ClassRepr> mySourceFileToClasses;
private IntObjectMaplet<File> myClassToSourceFile;
/**
* [short className] -> list of FQ names
*/
private IntIntMultiMaplet myShortClassNameIndex;
private IntIntTransientMultiMaplet myRemovedSuperClasses;
private IntIntTransientMultiMaplet myAddedSuperClasses;
@@ -96,6 +102,7 @@ public class Mappings {
myChangedClasses = new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR);
myChangedFiles = new THashSet(FileUtil.FILE_HASHING_STRATEGY);
myDeletedClasses = new HashSet<ClassRepr>(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR);
myAddedClasses = new HashSet<ClassRepr>(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR);
myDeltaIsTransient = base.myDeltaIsTransient;
myRootDir = new File(FileUtil.toSystemIndependentName(base.myRootDir.getAbsolutePath()) + File.separatorChar + "myDelta");
myContext = base.myContext;
@@ -112,6 +119,7 @@ public class Mappings {
myChangedClasses = null;
myChangedFiles = null;
myDeletedClasses = null;
myAddedClasses = null;
myDeltaIsTransient = transientDelta;
myRootDir = rootDir;
createImplementation();
@@ -132,6 +140,7 @@ public class Mappings {
if (myIsDelta && myDeltaIsTransient) {
myClassToSubclasses = new IntIntTransientMultiMaplet();
myClassToClassDependency = new IntIntTransientMultiMaplet();
myShortClassNameIndex = null;
mySourceFileToClasses = new ObjectObjectTransientMultiMaplet<File, ClassRepr>(FileUtil.FILE_HASHING_STRATEGY, ourClassSetConstructor);
myClassToSourceFile = new IntObjectTransientMaplet<File>();
}
@@ -141,6 +150,7 @@ public class Mappings {
}
myClassToSubclasses = new IntIntPersistentMultiMaplet(DependencyContext.getTableFile(myRootDir, CLASS_TO_SUBCLASSES), INT_KEY_DESCRIPTOR);
myClassToClassDependency = new IntIntPersistentMultiMaplet(DependencyContext.getTableFile(myRootDir, CLASS_TO_CLASS), INT_KEY_DESCRIPTOR);
myShortClassNameIndex = myIsDelta? null : new IntIntPersistentMultiMaplet(DependencyContext.getTableFile(myRootDir, SHORT_NAMES), INT_KEY_DESCRIPTOR);
mySourceFileToClasses = new ObjectObjectPersistentMultiMaplet<File, ClassRepr>(
DependencyContext.getTableFile(myRootDir, SOURCE_TO_CLASS), new FileKeyDescriptor(), ClassRepr.externalizer(myContext),
ourClassSetConstructor
@@ -1788,36 +1798,51 @@ public class Mappings {
for (final ClassRepr c : addedClasses) {
debug("Class name: ", c.name);
myDelta.addChangedClass(c.name);
myDelta.addAddedClass(c);
for (final int sup : c.getSupers()) {
myDelta.registerAddedSuperClass(c.name, sup);
}
if (!myEasyMode) {
final TIntHashSet depClasses = myClassToClassDependency.get(c.name);
if (depClasses != null) {
depClasses.forEach(new TIntProcedure() {
@Override
public boolean execute(int depClass) {
final File fName = myClassToSourceFile.get(depClass);
if (fName != null) {
if (myFilter == null || myFilter.accept(fName)) {
debug("Adding dependent file ", fName);
myAffectedFiles.add(fName);
}
}
return true;
}
});
if (!myEasyMode && !c.isAnonymous() && !c.isLocal()) {
final TIntHashSet toAffect = new TIntHashSet();
toAffect.add(c.name);
final TIntHashSet classes = myShortClassNameIndex.get(myContext.get(c.getShortName()));
if (classes != null) {
// affecting dependencies on all other classes with the same short name
toAffect.addAll(classes.toArray());
}
toAffect.forEach(new TIntProcedure() {
public boolean execute(int qName) {
final TIntHashSet depClasses = myClassToClassDependency.get(qName);
if (depClasses != null) {
affectCorrespondingSourceFiles(depClasses);
}
return true;
}
});
}
}
debug("End of added classes processing.");
}
private void affectCorrespondingSourceFiles(TIntHashSet toAffect) {
toAffect.forEach(new TIntProcedure() {
@Override
public boolean execute(int depClass) {
final File fName = myClassToSourceFile.get(depClass);
if (fName != null) {
if (myFilter == null || myFilter.accept(fName)) {
debug("Adding dependent file ", fName);
myAffectedFiles.add(fName);
}
}
return true;
}
});
}
private void calculateAffectedFiles(final DiffState state) {
debug("Checking dependent classes:");
@@ -1979,10 +2004,7 @@ public class Mappings {
}
}
private void cleanupRemovedClass(final Mappings delta,
@NotNull final ClassRepr cr,
final Set<UsageRepr.Usage> usages,
final IntIntMultiMaplet dependenciesTrashBin) {
private void cleanupRemovedClass(final Mappings delta, @NotNull final ClassRepr cr, final Set<UsageRepr.Usage> usages, final IntIntMultiMaplet dependenciesTrashBin) {
final int className = cr.name;
for (final int superSomething : cr.getSupers()) {
@@ -1994,6 +2016,9 @@ public class Mappings {
myClassToClassDependency.remove(className);
myClassToSubclasses.remove(className);
myClassToSourceFile.remove(className);
if (!cr.isLocal() && !cr.isAnonymous()) {
myShortClassNameIndex.removeFrom(myContext.get(cr.getShortName()), className);
}
}
public void integrate(final Mappings delta) {
@@ -2025,6 +2050,11 @@ public class Mappings {
for (final ClassRepr repr : delta.getDeletedClasses()) {
cleanupRemovedClass(delta, repr, repr.getUsages(), dependenciesTrashBin);
}
for (ClassRepr repr : delta.getAddedClasses()) {
if (!repr.isAnonymous() && !repr.isLocal()) {
myShortClassNameIndex.put(myContext.get(repr.getShortName()), repr.name);
}
}
final TIntHashSet superClasses = new TIntHashSet();
final IntIntTransientMultiMaplet addedSuperClasses = delta.getAddedSuperClasses();
@@ -2090,6 +2120,16 @@ public class Mappings {
myClassToSubclasses.putAll(delta.myClassToSubclasses);
myClassToSourceFile.putAll(delta.myClassToSourceFile);
mySourceFileToClasses.replaceAll(delta.mySourceFileToClasses);
delta.mySourceFileToClasses.forEachEntry(new TObjectObjectProcedure<File, Collection<ClassRepr>>() {
public boolean execute(File src, Collection<ClassRepr> classes) {
for (ClassRepr repr : classes) {
if (!repr.isAnonymous() && !repr.isLocal()) {
myShortClassNameIndex.put(myContext.get(repr.getShortName()), repr.name);
}
}
return true;
}
});
}
// updating classToClass dependencies
@@ -2224,6 +2264,7 @@ public class Mappings {
myClassToSourceFile.close();
if (!myIsDelta) {
myShortClassNameIndex.close();
// only close if you own the context
final DependencyContext context = myContext;
if (context != null) {
@@ -2247,6 +2288,7 @@ public class Mappings {
myClassToSourceFile.flush(memoryCachesOnly);
if (!myIsDelta) {
myShortClassNameIndex.flush(memoryCachesOnly);
// flush if you own the context
final DependencyContext context = myContext;
if (context != null) {
@@ -2312,6 +2354,14 @@ public class Mappings {
addChangedClass(cr.name);
}
private void addAddedClass(final ClassRepr cr) {
assert (myAddedClasses != null);
myAddedClasses.add(cr);
addChangedClass(cr.name);
}
private void addChangedClass(final int it) {
assert (myChangedClasses != null && myChangedFiles != null);
myChangedClasses.add(it);
@@ -2328,6 +2378,11 @@ public class Mappings {
return myDeletedClasses == null ? Collections.<ClassRepr>emptySet() : Collections.unmodifiableSet(myDeletedClasses);
}
@NotNull
private Set<ClassRepr> getAddedClasses() {
return myAddedClasses == null ? Collections.<ClassRepr>emptySet() : Collections.unmodifiableSet(myAddedClasses);
}
private TIntHashSet getChangedClasses() {
return myChangedClasses;
}
@@ -2390,6 +2445,7 @@ public class Mappings {
myClassToClassDependency,
mySourceFileToClasses,
myClassToSourceFile,
myShortClassNameIndex
};
final String[] info = {
@@ -2397,6 +2453,7 @@ public class Mappings {
"ClassToClassDependency",
"SourceFileToClasses",
"ClassToSourceFile",
"ShortClassNameIndex"
};
for (int i = 0; i < data.length; i++) {
@@ -41,7 +41,7 @@ import java.util.concurrent.ConcurrentMap;
* Date: 10/7/11
*/
public class BuildDataManager implements StorageOwner {
private static final int VERSION = 20;
private static final int VERSION = 21;
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.storage.BuildDataManager");
private static final String SRC_TO_FORM_STORAGE = "src-form";
private static final String MAPPINGS_STORAGE = "mappings";
@@ -113,4 +113,9 @@ public class CommonTest extends IncrementalTestCase {
public void testAddDuplicateClass() throws Exception {
doTest();
}
public void testAddClassHidingImportedClass() throws Exception {
doTest();
}
}
@@ -23,7 +23,6 @@ import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.editor.Document;
@@ -114,6 +113,13 @@ public class FindInProjectUtil {
if (model.getModuleName() == null || editor == null) {
model.setDirectoryName(directoryName);
model.setProjectScope(directoryName == null && module == null && !model.isCustomScope() || editor != null);
// for convenience set directory name to directory of current file, note that we doesn't change default projectScope
if (directoryName == null) {
VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(dataContext);
if (virtualFile != null && !virtualFile.isDirectory()) virtualFile = virtualFile.getParent();
if (virtualFile != null) model.setDirectoryName(virtualFile.getPresentableUrl());
}
}
}
@@ -56,6 +56,10 @@ public class MavenModuleMap {
public boolean resolveToModule(Artifact artifact) {
String extension = artifact.getArtifactHandler().getExtension();
if ("jar".equals(extension) && "test-jar".equals(artifact.getType())) {
extension = "test-jar";
}
File file = findArtifact(artifact.getGroupId(), artifact.getArtifactId(), extension, artifact.getBaseVersion());
if(file == null) {
@@ -52,7 +52,12 @@ public class MyWorkspaceReader implements WorkspaceReader {
}
public File findArtifact(Artifact artifact) {
return MavenModuleMap.getInstance().findArtifact(artifact.getGroupId(), artifact.getArtifactId(), artifact.getExtension(),
String type = artifact.getExtension();
if ("jar".equals(type) && "tests".equals(artifact.getClassifier())) {
type = "test-jar";
}
return MavenModuleMap.getInstance().findArtifact(artifact.getGroupId(), artifact.getArtifactId(), type,
artifact.getBaseVersion());
}
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../maven3-server-impl/lib/maven3/lib/maven-core-3.0.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../maven3-server-impl/lib/maven3/lib/plexus-component-annotations-1.5.5.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/eclipse-aether/aether-api-0.9.0.M2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module" module-name="maven-artifact-resolver-m2" />
</component>
</module>
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<component-set>
<components>
<component>
<role>org.eclipse.aether.repository.WorkspaceReader</role>
<role-hint>ide</role-hint>
<implementation>org.jetbrains.idea.maven.artifactResolver.IntelliJWorkspaceReaderM31</implementation>
<description />
<isolated-realm>false</isolated-realm>
</component>
</components>
</component-set>
@@ -0,0 +1,67 @@
/*
* Copyright 2000-2013 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.idea.maven.artifactResolver;
import org.codehaus.plexus.component.annotations.Component;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.repository.WorkspaceReader;
import org.eclipse.aether.repository.WorkspaceRepository;
import org.jetbrains.idea.maven.artifactResolver.common.MavenModuleMap;
import java.io.File;
import java.util.Collections;
import java.util.List;
/**
* @author Sergey Evdokimov
*/
@Component(role = WorkspaceReader.class, hint = "ide")
public class IntelliJWorkspaceReaderM31 implements WorkspaceReader {
private final WorkspaceRepository myWorkspaceRepository;
public IntelliJWorkspaceReaderM31() {
myWorkspaceRepository = new WorkspaceRepository("ide", getClass());
}
@Override
public int hashCode() {
return 311;
}
@Override
public boolean equals(Object o) {
return o instanceof IntelliJWorkspaceReaderM31;
}
public WorkspaceRepository getRepository() {
return myWorkspaceRepository;
}
public File findArtifact(Artifact artifact) {
String type = artifact.getExtension();
if ("jar".equals(type) && "tests".equals(artifact.getClassifier())) {
type = "test-jar";
}
return MavenModuleMap.getInstance().findArtifact(artifact.getGroupId(), artifact.getArtifactId(), type,
artifact.getBaseVersion());
}
public List<String> findVersions(Artifact artifact) {
return Collections.emptyList();
}
}
@@ -0,0 +1,22 @@
/*
* Copyright 2000-2013 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.idea.maven.artifactResolver;
/**
* @author Sergey Evdokimov
*/
public class MavenArtifactResolvedM31RtMarker {
}
+1
View File
@@ -59,6 +59,7 @@
<orderEntry type="module" module-name="jps-model-impl" />
<orderEntry type="module" module-name="maven-jps-plugin" />
<orderEntry type="module" module-name="maven-artifact-resolver-m3" />
<orderEntry type="module" module-name="maven-artifact-resolver-m31" />
<orderEntry type="module" module-name="spellchecker" />
<orderEntry type="module" module-name="vcs-api" />
</component>
@@ -47,6 +47,7 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.artifactResolver.MavenArtifactResolvedM2RtMarker;
import org.jetbrains.idea.maven.artifactResolver.MavenArtifactResolvedM31RtMarker;
import org.jetbrains.idea.maven.artifactResolver.MavenArtifactResolvedM3RtMarker;
import org.jetbrains.idea.maven.artifactResolver.common.MavenModuleMap;
import org.jetbrains.idea.maven.project.MavenGeneralSettings;
@@ -126,7 +127,7 @@ public class MavenExternalParameters {
if (project != null && parameters.isResolveToWorkspace()) {
try {
String resolverJar = getArtifactResolverJar(MavenUtil.isMaven3(mavenHome));
String resolverJar = getArtifactResolverJar(MavenUtil.getMavenVersion(mavenHome));
confFile = patchConfFile(confFile, resolverJar);
File modulesPathsFile = dumpModulesPaths(project);
@@ -196,11 +197,24 @@ public class MavenExternalParameters {
finally {
sc.close();
}
}
private static String getArtifactResolverJar(boolean isMaven3) throws IOException {
Class marker = isMaven3 ? MavenArtifactResolvedM3RtMarker.class : MavenArtifactResolvedM2RtMarker.class;
private static String getArtifactResolverJar(@Nullable String mavenVersion) throws IOException {
boolean isMaven3;
Class marker;
if (mavenVersion != null && mavenVersion.compareTo("3.1.0") >= 0) {
isMaven3 = true;
marker = MavenArtifactResolvedM31RtMarker.class;
}
else if (mavenVersion != null && mavenVersion.compareTo("3.0.0") >= 0) {
isMaven3 = true;
marker = MavenArtifactResolvedM3RtMarker.class;
}
else {
isMaven3 = false;
marker = MavenArtifactResolvedM2RtMarker.class;
}
File classDirOrJar = new File(PathUtil.getJarPathForClass(marker));
@@ -246,6 +260,12 @@ public class MavenExternalParameters {
+ ':' + mavenProject.getMavenId().getVersion(),
mavenProject.getFile().getPath());
res.setProperty(mavenProject.getMavenId().getGroupId()
+ ':' + mavenProject.getMavenId().getArtifactId()
+ ":test-jar"
+ ':' + mavenProject.getMavenId().getVersion(),
mavenProject.getTestOutputDirectory());
res.setProperty(mavenProject.getMavenId().getGroupId()
+ ':' + mavenProject.getMavenId().getArtifactId()
+ ':' + mavenProject.getPackaging()
@@ -637,6 +637,7 @@ PARSE.expected.comma=',' expected
PARSE.expected.colon=':' expected
PARSE.expected.rpar=')' expected
PARSE.expected.lpar='(' expected
PARSE.expected.rbrace='}' expected
PARSE.expected.tick='`' (backtick) expected
PARSE.expected.name=name expected
PARSE.expected.colon.or.rbracket=':' or ']' expected
@@ -236,7 +236,7 @@ public class ExpressionParsing extends Parsing {
break;
}
}
myBuilder.advanceLexer();
checkMatches(PyTokenTypes.RBRACE, message("PARSE.expected.rbrace"));
startMarker.done(PyElementTypes.DICT_LITERAL_EXPRESSION);
}
}
@@ -264,7 +264,7 @@ public class ExpressionParsing extends Parsing {
break;
}
}
myBuilder.advanceLexer();
checkMatches(PyTokenTypes.RBRACE, message("PARSE.expected.rbrace"));
startMarker.done(PyElementTypes.SET_LITERAL_EXPRESSION);
}
@@ -1,2 +0,0 @@
def foo(bar):
""" Variable bar """
@@ -0,0 +1,3 @@
a = {
'b': 'c',
]
@@ -0,0 +1,24 @@
PyFile:NotClosedBraceDict.py
PyAssignmentStatement
PyTargetExpression: a
PsiElement(Py:IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(Py:EQ)('=')
PsiWhiteSpace(' ')
PyDictLiteralExpression
PsiElement(Py:LBRACE)('{')
PsiWhiteSpace('\n ')
PyKeyValueExpression
PyStringLiteralExpression: b
PsiElement(Py:SINGLE_QUOTED_STRING)(''b'')
PsiElement(Py:COLON)(':')
PsiWhiteSpace(' ')
PyStringLiteralExpression: c
PsiElement(Py:SINGLE_QUOTED_STRING)(''c'')
PsiElement(Py:COMMA)(',')
PsiErrorElement:'}' expected
<empty list>
PsiWhiteSpace('\n ')
PsiElement(Py:RBRACKET)(']')
PsiErrorElement:Statement expected, found Py:RBRACKET
<empty list>
+1
View File
@@ -0,0 +1 @@
a = {'b',]
+17
View File
@@ -0,0 +1,17 @@
PyFile:NotClosedBraceSet.py
PyAssignmentStatement
PyTargetExpression: a
PsiElement(Py:IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(Py:EQ)('=')
PsiWhiteSpace(' ')
PySetLiteralExpression
PsiElement(Py:LBRACE)('{')
PyStringLiteralExpression: b
PsiElement(Py:SINGLE_QUOTED_STRING)(''b'')
PsiElement(Py:COMMA)(',')
PsiErrorElement:'}' expected
<empty list>
PsiElement(Py:RBRACKET)(']')
PsiErrorElement:Statement expected, found Py:RBRACKET
<empty list>
@@ -15,9 +15,12 @@
*/
package com.jetbrains.python;
import com.google.common.collect.Lists;
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
import com.intellij.codeInsight.lookup.Lookup;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.jetbrains.python.documentation.DocStringFormat;
import com.jetbrains.python.documentation.PyDocumentationSettings;
import com.jetbrains.python.fixtures.PyTestCase;
@@ -387,8 +390,10 @@ public class PythonCompletionTest extends PyTestCase {
final PyDocumentationSettings settings = PyDocumentationSettings.getInstance(myFixture.getModule());
settings.setFormat(DocStringFormat.PLAIN);
myFixture.configureByFile("completion/identifiersInPlainDocstring.py");
myFixture.completeBasic();
myFixture.checkResultByFile("completion/identifiersInPlainDocstring.after.py");
final LookupElement[] elements = myFixture.completeBasic();
assertNotNull(elements);
assertContainsElements(Lists.newArrayList(elements),
LookupElementBuilder.create("bar").withAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE));
}
public void testPep328Completion() { // PY-3409
@@ -430,6 +430,14 @@ public class PythonParsingTest extends ParsingTestCase {
doTest();
}
public void testNotClosedBraceDict() {
doTest();
}
public void testNotClosedBraceSet() {
doTest(LanguageLevel.PYTHON33);
}
public void doTest(LanguageLevel languageLevel) {
LanguageLevel prev = myLanguageLevel;
myLanguageLevel = languageLevel;