mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -79,14 +79,14 @@ public class HierarchyServiceImpl extends HierarchyService {
|
||||
}
|
||||
|
||||
private void loadUnits(BitSet files, int[] indexKeys, StubEnter stubEnter) {
|
||||
FileBasedIndexImpl.IdValueProcessor<IndexTree.Unit> processor = new FileBasedIndexImpl.IdValueProcessor<IndexTree.Unit>() {
|
||||
FileBasedIndexImpl.IdValueProcessor<SerializedUnit> processor = new FileBasedIndexImpl.IdValueProcessor<SerializedUnit>() {
|
||||
final ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator();
|
||||
int count = 0;
|
||||
@Override
|
||||
public boolean process(int fileId, IndexTree.Unit unit) {
|
||||
public boolean process(int fileId, SerializedUnit unit) {
|
||||
if (indicator != null && ++count % 128 == 0) indicator.checkCanceled();
|
||||
if (files.get(fileId)) {
|
||||
stubEnter.unitEnter(unit, fileId);
|
||||
unit.readUnit(stubEnter, fileId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -15,10 +15,16 @@
|
||||
*/
|
||||
package com.intellij.psi.stubsHierarchy.impl;
|
||||
|
||||
import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.BitUtil;
|
||||
import com.intellij.util.io.DataInputOutputUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class Imports {
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
class Imports {
|
||||
public final static long[] EMPTY_ARRAY = ArrayUtil.EMPTY_LONG_ARRAY;
|
||||
|
||||
public static final int onDemandMask = 1 << 29;
|
||||
@@ -50,4 +56,46 @@ public class Imports {
|
||||
if (onDemand) lower |= onDemandMask;
|
||||
return (((long)alias) << 32) | lower;
|
||||
}
|
||||
|
||||
private final static int IS_STATIC = 1;
|
||||
private final static int IS_ON_DEMAND = 2;
|
||||
private final static int HAS_ALIAS = 4;
|
||||
|
||||
static void writeImports(@NotNull DataOutput out, IndexTree.Unit value) throws IOException {
|
||||
DataInputOutputUtil.writeINT(out, value.imports.length);
|
||||
for (IndexTree.Import anImport : value.imports) {
|
||||
writeImport(out, anImport);
|
||||
}
|
||||
}
|
||||
|
||||
static long[] readImports(UnitInputStream in) throws IOException {
|
||||
int importCount = DataInputOutputUtil.readINT(in);
|
||||
long[] imports = importCount == 0 ? EMPTY_ARRAY : new long[importCount];
|
||||
for (int i = 0; i < importCount; i++) {
|
||||
imports[i] = readImport(in);
|
||||
}
|
||||
return imports;
|
||||
}
|
||||
|
||||
private static void writeImport(@NotNull DataOutput out, IndexTree.Import anImport) throws IOException {
|
||||
SerializedUnit.writeQualifiedName(out, anImport.myFullname);
|
||||
boolean hasAlias = anImport.myAlias != 0;
|
||||
int flags = 0;
|
||||
flags = BitUtil.set(flags, IS_STATIC, anImport.myStaticImport);
|
||||
flags = BitUtil.set(flags, IS_ON_DEMAND, anImport.myOnDemand);
|
||||
flags = BitUtil.set(flags, HAS_ALIAS, hasAlias);
|
||||
out.writeByte(flags);
|
||||
if (hasAlias) {
|
||||
out.writeInt(anImport.myAlias);
|
||||
}
|
||||
}
|
||||
|
||||
private static long readImport(UnitInputStream in) throws IOException {
|
||||
int fullname = in.names.readQualifiedName(in);
|
||||
int flags = in.readByte();
|
||||
return mkImport(fullname,
|
||||
BitUtil.isSet(flags, IS_STATIC), BitUtil.isSet(flags, IS_ON_DEMAND),
|
||||
BitUtil.isSet(flags, HAS_ALIAS) ? in.readInt() : 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,9 +18,14 @@ package com.intellij.psi.stubsHierarchy.impl;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.psi.CommonClassNames;
|
||||
import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree;
|
||||
import com.intellij.util.io.DataInputOutputUtil;
|
||||
import gnu.trove.TIntArrayList;
|
||||
import gnu.trove.TLongIntHashMap;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
class NameEnvironment extends UserDataHolderBase {
|
||||
public static final int OBJECT_NAME = IndexTree.hashIdentifier("Object");
|
||||
public static final int NO_NAME = 0;
|
||||
@@ -67,6 +72,22 @@ class NameEnvironment extends UserDataHolderBase {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see SerializedUnit#writeQualifiedName(DataOutput, int[])
|
||||
*/
|
||||
@QNameId int readQualifiedName(DataInput in) throws IOException {
|
||||
int id = 0;
|
||||
int len = DataInputOutputUtil.readINT(in);
|
||||
for (int i = 0; i < len; i++) {
|
||||
id = qualifiedName(id, in.readInt());
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
int memberQualifiedName(@QNameId int ownerName, @ShortName int name) {
|
||||
return name == NO_NAME || ownerName < 0 ? -1 : qualifiedName(ownerName, name);
|
||||
}
|
||||
|
||||
@QNameId int qualifiedName(@QNameId int prefix, @ShortName int shortName) {
|
||||
int existing = findExistingName(prefix, shortName);
|
||||
return existing >= 0 ? existing : addName(prefix, shortName);
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi.stubsHierarchy.impl;
|
||||
|
||||
import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree;
|
||||
import com.intellij.psi.stubsHierarchy.impl.Symbol.ClassSymbol;
|
||||
import com.intellij.psi.stubsHierarchy.impl.Symbol.MemberSymbol;
|
||||
import com.intellij.psi.stubsHierarchy.impl.Symbol.PackageSymbol;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.io.DataInputOutputUtil;
|
||||
import com.intellij.util.io.DataOutputStream;
|
||||
import com.intellij.util.io.UnsyncByteArrayInputStream;
|
||||
import com.intellij.util.io.UnsyncByteArrayOutputStream;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
class SerializedUnit {
|
||||
private final byte[] myBytes;
|
||||
|
||||
SerializedUnit(byte[] bytes) {
|
||||
myBytes = bytes;
|
||||
}
|
||||
|
||||
SerializedUnit(IndexTree.Unit unit) {
|
||||
try {
|
||||
//noinspection IOResourceOpenedButNotSafelyClosed
|
||||
UnsyncByteArrayOutputStream stream = new UnsyncByteArrayOutputStream();
|
||||
writeUnit(new DataOutputStream(stream), unit);
|
||||
myBytes = stream.toByteArray();
|
||||
}
|
||||
catch (IOException impossible) {
|
||||
throw new RuntimeException(impossible);
|
||||
}
|
||||
}
|
||||
|
||||
byte[] getSerializedBytes() {
|
||||
return myBytes;
|
||||
}
|
||||
|
||||
void readUnit(StubEnter stubEnter, int fileId) {
|
||||
try {
|
||||
enterUnit(new UnitInputStream(new UnsyncByteArrayInputStream(myBytes), fileId, stubEnter));
|
||||
}
|
||||
catch (IOException impossible) {
|
||||
throw new RuntimeException(impossible);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see NameEnvironment#readQualifiedName(DataInput)
|
||||
*/
|
||||
static void writeQualifiedName(DataOutput out, @QNameId int[] array) throws IOException {
|
||||
DataInputOutputUtil.writeINT(out, array.length);
|
||||
for (int i : array) {
|
||||
out.writeInt(i);
|
||||
}
|
||||
}
|
||||
|
||||
// unit
|
||||
|
||||
private static void writeUnit(@NotNull DataOutput out, IndexTree.Unit value) throws IOException {
|
||||
writeQualifiedName(out, value.myPackageName);
|
||||
out.writeByte(value.myUnitType);
|
||||
if (value.myUnitType != IndexTree.BYTECODE) {
|
||||
Imports.writeImports(out, value);
|
||||
}
|
||||
// class Declaration
|
||||
DataInputOutputUtil.writeINT(out, value.myDecls.length);
|
||||
for (IndexTree.ClassDecl def : value.myDecls) {
|
||||
saveClassDecl(out, def);
|
||||
}
|
||||
}
|
||||
|
||||
private static void enterUnit(UnitInputStream in) throws IOException {
|
||||
PackageSymbol pkg = in.stubEnter.enterPackage(in);
|
||||
byte type = in.readByte();
|
||||
long[] imports = type == IndexTree.BYTECODE ? Imports.EMPTY_ARRAY : Imports.readImports(in);
|
||||
UnitInfo unitInfo = UnitInfo.mkUnitInfo(type, imports);
|
||||
|
||||
int classCount = DataInputOutputUtil.readINT(in);
|
||||
for (int i = 0; i < classCount; i++) {
|
||||
readClassDecl(in, unitInfo, pkg, pkg.myQualifiedName);
|
||||
}
|
||||
}
|
||||
|
||||
// class
|
||||
|
||||
private static void saveClassDecl(@NotNull DataOutput out, IndexTree.ClassDecl value) throws IOException {
|
||||
DataInputOutputUtil.writeINT(out, value.myStubId);
|
||||
DataInputOutputUtil.writeINT(out, value.myMods);
|
||||
out.writeInt(value.myName);
|
||||
writeSupers(out, value);
|
||||
writeMembers(out, value.myDecls);
|
||||
}
|
||||
|
||||
private static ClassSymbol readClassDecl(UnitInputStream in, UnitInfo info, Symbol owner, @QNameId int ownerName) throws IOException {
|
||||
int stubId = DataInputOutputUtil.readINT(in);
|
||||
int mods = DataInputOutputUtil.readINT(in);
|
||||
@ShortName int name = in.readInt();
|
||||
@QNameId int[] superNames = readSupers(in);
|
||||
|
||||
@QNameId int qname = in.names.memberQualifiedName(ownerName, name);
|
||||
ClassSymbol symbol = in.stubEnter.classEnter(info, owner, stubId, mods, name, superNames, qname, in.fileId);
|
||||
|
||||
readMembers(in, info, qname, symbol);
|
||||
return symbol;
|
||||
}
|
||||
|
||||
// supers
|
||||
|
||||
private static void writeSupers(@NotNull DataOutput out, IndexTree.ClassDecl value) throws IOException {
|
||||
DataInputOutputUtil.writeINT(out, value.mySupers.length);
|
||||
for (int[] aSuper : value.mySupers) {
|
||||
writeQualifiedName(out, aSuper);
|
||||
}
|
||||
}
|
||||
|
||||
private static @QNameId int[] readSupers(UnitInputStream in) throws IOException {
|
||||
@QNameId int[] superNames = new int[DataInputOutputUtil.readINT(in)];
|
||||
for (int i = 0; i < superNames.length; i++) {
|
||||
superNames[i] = in.names.readQualifiedName(in);
|
||||
}
|
||||
return superNames;
|
||||
}
|
||||
|
||||
// members
|
||||
|
||||
private static void writeMembers(@NotNull DataOutput out, IndexTree.Decl[] decls) throws IOException {
|
||||
DataInputOutputUtil.writeINT(out, decls.length);
|
||||
for (IndexTree.Decl def : decls) {
|
||||
saveDecl(out, def);
|
||||
}
|
||||
}
|
||||
|
||||
private static void readMembers(UnitInputStream in,
|
||||
UnitInfo info,
|
||||
@QNameId int ownerName,
|
||||
MemberSymbol symbol) throws IOException {
|
||||
int memberCount = DataInputOutputUtil.readINT(in);
|
||||
if (memberCount == 0) return;
|
||||
|
||||
List<ClassSymbol> members = new ArrayList<>();
|
||||
for (int i = 0; i < memberCount; i++) {
|
||||
ContainerUtil.addIfNotNull(members, readDecl(in, info, symbol, ownerName));
|
||||
}
|
||||
symbol.setMembers(members);
|
||||
}
|
||||
|
||||
// decl: class or member
|
||||
|
||||
private static void saveDecl(@NotNull DataOutput out, IndexTree.Decl value) throws IOException {
|
||||
if (value instanceof IndexTree.ClassDecl) {
|
||||
out.writeBoolean(true);
|
||||
saveClassDecl(out, (IndexTree.ClassDecl)value);
|
||||
} else if (value instanceof IndexTree.MemberDecl) {
|
||||
out.writeBoolean(false);
|
||||
writeMembers(out, ((IndexTree.MemberDecl)value).myDecls);
|
||||
}
|
||||
}
|
||||
|
||||
private static ClassSymbol readDecl(UnitInputStream in, UnitInfo info, Symbol owner, @QNameId int ownerName) throws IOException {
|
||||
if (in.readBoolean()) {
|
||||
return readClassDecl(in, info, owner, ownerName);
|
||||
}
|
||||
|
||||
readMembers(in, info, ownerName, new MemberSymbol(owner));
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return this == o || o instanceof SerializedUnit && Arrays.equals(myBytes, ((SerializedUnit)o).myBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = myBytes.length;
|
||||
int length = Math.min(30, myBytes.length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
result = 31 * result + myBytes[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
class UnitInputStream extends DataInputStream {
|
||||
final int fileId;
|
||||
final StubEnter stubEnter;
|
||||
final NameEnvironment names;
|
||||
|
||||
UnitInputStream(InputStream in, int fileId, StubEnter stubEnter) {
|
||||
super(in);
|
||||
this.fileId = fileId;
|
||||
this.stubEnter = stubEnter;
|
||||
this.names = stubEnter.myNameEnvironment;
|
||||
}
|
||||
}
|
||||
@@ -19,13 +19,15 @@ import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree;
|
||||
import com.intellij.util.BitUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.intellij.psi.stubsHierarchy.impl.Symbol.*;
|
||||
import static com.intellij.psi.stubsHierarchy.impl.Symbol.ClassSymbol;
|
||||
import static com.intellij.psi.stubsHierarchy.impl.Symbol.PackageSymbol;
|
||||
|
||||
public class StubEnter {
|
||||
private final NameEnvironment myNameEnvironment;
|
||||
final NameEnvironment myNameEnvironment;
|
||||
private final Symbols mySymbols;
|
||||
private final StubHierarchyConnector myStubHierarchyConnector;
|
||||
|
||||
@@ -37,85 +39,30 @@ public class StubEnter {
|
||||
myStubHierarchyConnector = new StubHierarchyConnector(myNameEnvironment, symbols);
|
||||
}
|
||||
|
||||
void unitEnter(IndexTree.Unit unit, int fileId) {
|
||||
@QNameId int pkgName = unit.myPackageName.length > 0 ? myNameEnvironment.internQualifiedName(unit.myPackageName) : 0;
|
||||
enter(unit.myDecls, UnitInfo.mkUnitInfo(unit.myUnitType, internImports(unit)), mySymbols.enterPackage(pkgName), pkgName, fileId);
|
||||
PackageSymbol enterPackage(DataInput in) throws IOException {
|
||||
return mySymbols.enterPackage(myNameEnvironment.readQualifiedName(in));
|
||||
}
|
||||
|
||||
private long[] internImports(IndexTree.Unit unit) {
|
||||
long[] imports = unit.imports.length == 0 ? Imports.EMPTY_ARRAY : new long[unit.imports.length];
|
||||
for (int i = 0; i < unit.imports.length; i++) {
|
||||
imports[i] = processImport(unit.imports[i]);
|
||||
}
|
||||
return imports;
|
||||
}
|
||||
|
||||
private long processImport(IndexTree.Import anImport) {
|
||||
int fullname = myNameEnvironment.internQualifiedName(anImport.myFullname);
|
||||
return Imports.mkImport(fullname, anImport.myStaticImport, anImport.myOnDemand, anImport.myAlias);
|
||||
}
|
||||
|
||||
private void enter(IndexTree.ClassDecl[] trees, UnitInfo info, Symbol owner, @QNameId int ownerName, int fileId) {
|
||||
for (IndexTree.ClassDecl tree : trees) {
|
||||
enter(tree, info, owner, ownerName, fileId);
|
||||
}
|
||||
}
|
||||
|
||||
private ClassSymbol[] enter(IndexTree.Decl[] trees, UnitInfo info, Symbol owner, @QNameId int ownerName, int fileId) {
|
||||
ClassSymbol[] members = new ClassSymbol[trees.length];
|
||||
int i = 0;
|
||||
for (IndexTree.Decl tree : trees) {
|
||||
ClassSymbol member = enter(tree, info, owner, ownerName, fileId);
|
||||
if (member != null && member.myShortName != 0) {
|
||||
members[i++] = member;
|
||||
}
|
||||
}
|
||||
if (i == 0) return ClassSymbol.EMPTY_ARRAY;
|
||||
|
||||
if (i < members.length) {
|
||||
members = Arrays.copyOf(members, i);
|
||||
}
|
||||
Arrays.sort(members, CLASS_SYMBOL_BY_NAME_COMPARATOR);
|
||||
return members;
|
||||
}
|
||||
|
||||
private ClassSymbol enter(IndexTree.Decl tree, UnitInfo info, Symbol owner, @QNameId int ownerName, int fileId) {
|
||||
if (tree instanceof IndexTree.ClassDecl) {
|
||||
return classEnter((IndexTree.ClassDecl)tree, info, owner, ownerName, fileId);
|
||||
}
|
||||
if (tree instanceof IndexTree.MemberDecl) {
|
||||
memberEnter((IndexTree.MemberDecl)tree, info, owner, ownerName, fileId);
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void memberEnter(IndexTree.MemberDecl tree, UnitInfo info, Symbol owner, @QNameId int ownerName, int fileId) {
|
||||
MemberSymbol mc = new MemberSymbol(owner);
|
||||
mc.setMembers(enter(tree.myDecls, info, mc, ownerName, fileId));
|
||||
}
|
||||
|
||||
private ClassSymbol classEnter(IndexTree.ClassDecl tree, UnitInfo info, Symbol owner, @QNameId int ownerName, int fileId) {
|
||||
int flags = checkFlags(tree.myMods, owner, info.getType() == IndexTree.BYTECODE);
|
||||
|
||||
int name = tree.myName;
|
||||
@QNameId int qname = name == NameEnvironment.NO_NAME || ownerName < 0 ? -1
|
||||
: myNameEnvironment.qualifiedName(ownerName, name);
|
||||
@CompactArray(QualifiedName.class) Object supers = internSupers(tree.myMods, tree.mySupers);
|
||||
ClassSymbol classSymbol = mySymbols.enterClass(fileId, tree.myStubId, flags, name, owner, info, supers, qname);
|
||||
ClassSymbol classEnter(UnitInfo info,
|
||||
Symbol owner,
|
||||
int stubId,
|
||||
int mods,
|
||||
@ShortName int name,
|
||||
@QNameId int[] superNames,
|
||||
@QNameId int qname, int fileId) throws IOException {
|
||||
int flags = checkFlags(mods, owner, info.getType() == IndexTree.BYTECODE);
|
||||
@CompactArray(QualifiedName.class) Object supers = internSupers(mods, superNames);
|
||||
|
||||
ClassSymbol classSymbol = mySymbols.enterClass(fileId, stubId, flags, name, owner, info, supers, qname);
|
||||
if (uncompleted != null) {
|
||||
uncompleted.add(classSymbol);
|
||||
}
|
||||
if (tree.myDecls.length > 0) {
|
||||
classSymbol.setMembers(enter(tree.myDecls, info, classSymbol, qname, fileId));
|
||||
}
|
||||
return classSymbol;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@CompactArray(QualifiedName.class)
|
||||
private Object internSupers(int flags, int[][] superNames) {
|
||||
Object internSupers(int flags, int[] superNames) {
|
||||
if (BitUtil.isSet(flags, IndexTree.ANNOTATION)) {
|
||||
return myNameEnvironment.java_lang_annotation_Annotation;
|
||||
}
|
||||
@@ -125,12 +72,12 @@ public class StubEnter {
|
||||
return isEnum ? myNameEnvironment.java_lang_Enum : null;
|
||||
}
|
||||
if (superNames.length == 1 && !isEnum) {
|
||||
return new QualifiedName(myNameEnvironment.internQualifiedName(superNames[0]));
|
||||
return new QualifiedName(superNames[0]);
|
||||
}
|
||||
|
||||
QualifiedName[] array = new QualifiedName[superNames.length + (isEnum ? 1 : 0)];
|
||||
for (int i = 0; i < superNames.length; i++) {
|
||||
array[i] = new QualifiedName(myNameEnvironment.internQualifiedName(superNames[i]));
|
||||
array[i] = new QualifiedName(superNames[i]);
|
||||
}
|
||||
if (isEnum) {
|
||||
array[array.length - 1] = myNameEnvironment.java_lang_Enum;
|
||||
|
||||
@@ -21,14 +21,17 @@ import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileWithId;
|
||||
import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree;
|
||||
import com.intellij.psi.impl.java.stubs.index.JavaUnitDescriptor;
|
||||
import com.intellij.psi.stubsHierarchy.StubHierarchyIndexer;
|
||||
import com.intellij.util.indexing.*;
|
||||
import com.intellij.util.io.DataExternalizer;
|
||||
import com.intellij.util.io.DataInputOutputUtil;
|
||||
import com.intellij.util.io.EnumeratorIntegerDescriptor;
|
||||
import com.intellij.util.io.KeyDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.stream.IntStream;
|
||||
@@ -36,29 +39,29 @@ import java.util.stream.IntStream;
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class StubHierarchyIndex extends FileBasedIndexExtension<Integer, IndexTree.Unit> implements PsiDependentIndex {
|
||||
public class StubHierarchyIndex extends FileBasedIndexExtension<Integer, SerializedUnit> implements PsiDependentIndex {
|
||||
private static final int KEY_COUNT = 20;
|
||||
static final int[] BINARY_KEYS = IntStream.rangeClosed(1, KEY_COUNT).toArray();
|
||||
static final int[] SOURCE_KEYS = IntStream.rangeClosed(-KEY_COUNT, -1).toArray();
|
||||
static final ID<Integer, IndexTree.Unit> INDEX_ID = ID.create("jvm.hierarchy");
|
||||
static final ID<Integer, SerializedUnit> INDEX_ID = ID.create("jvm.hierarchy");
|
||||
private static final StubHierarchyIndexer[] ourIndexers = StubHierarchyIndexer.EP_NAME.getExtensions();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ID<Integer, IndexTree.Unit> getName() {
|
||||
public ID<Integer, SerializedUnit> getName() {
|
||||
return INDEX_ID;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DataIndexer<Integer, IndexTree.Unit, FileContent> getIndexer() {
|
||||
public DataIndexer<Integer, SerializedUnit, FileContent> getIndexer() {
|
||||
return inputData -> {
|
||||
for (StubHierarchyIndexer indexer : ourIndexers) {
|
||||
VirtualFile file = inputData.getFile();
|
||||
IndexTree.Unit unit = indexer.handlesFile(file) ? indexer.indexFile(inputData) : null;
|
||||
if (unit != null && unit.myDecls.length > 0) {
|
||||
int[] keys = file.getFileType().isBinary() ? BINARY_KEYS : SOURCE_KEYS;
|
||||
return Collections.singletonMap(keys[((VirtualFileWithId) file).getId() % keys.length], unit);
|
||||
return Collections.singletonMap(keys[((VirtualFileWithId) file).getId() % keys.length], new SerializedUnit(unit));
|
||||
}
|
||||
}
|
||||
return Collections.emptyMap();
|
||||
@@ -73,13 +76,27 @@ public class StubHierarchyIndex extends FileBasedIndexExtension<Integer, IndexTr
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DataExternalizer<IndexTree.Unit> getValueExternalizer() {
|
||||
return JavaUnitDescriptor.INSTANCE;
|
||||
public DataExternalizer<SerializedUnit> getValueExternalizer() {
|
||||
return new DataExternalizer<SerializedUnit>() {
|
||||
@Override
|
||||
public void save(@NotNull DataOutput out, SerializedUnit value) throws IOException {
|
||||
byte[] bytes = value.getSerializedBytes();
|
||||
DataInputOutputUtil.writeINT(out, bytes.length);
|
||||
out.write(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerializedUnit read(@NotNull DataInput in) throws IOException {
|
||||
byte[] bytes = new byte[DataInputOutputUtil.readINT(in)];
|
||||
in.readFully(bytes);
|
||||
return new SerializedUnit(bytes);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVersion() {
|
||||
return IndexTree.STUB_HIERARCHY_ENABLED ? 5 + Arrays.stream(ourIndexers).mapToInt(StubHierarchyIndexer::getVersion).sum() : 0;
|
||||
return IndexTree.STUB_HIERARCHY_ENABLED ? 6 + Arrays.stream(ourIndexers).mapToInt(StubHierarchyIndexer::getVersion).sum() : 0;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package com.intellij.psi.stubsHierarchy.impl;
|
||||
|
||||
import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree;
|
||||
import com.intellij.util.BitUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -48,11 +46,10 @@ public class StubResolver {
|
||||
return result;
|
||||
}
|
||||
|
||||
int k = processPackages ? IndexTree.CLASS | IndexTree.PACKAGE : IndexTree.CLASS;
|
||||
Set<Symbol> prev = resolveBase(sym, prefix, true);
|
||||
Set<Symbol> result = new HashSet<>();
|
||||
for (Symbol symbol : prev) {
|
||||
selectSym(symbol, shortName, k, result);
|
||||
selectSym(symbol, shortName, processPackages, result);
|
||||
}
|
||||
if (result.isEmpty()) {
|
||||
throw IncompleteHierarchyException.INSTANCE;
|
||||
@@ -79,30 +76,26 @@ public class StubResolver {
|
||||
for (Symbol s = startScope; s != null; s = s.myOwner)
|
||||
findMemberType(s, name, symbols);
|
||||
// type from current package
|
||||
findIdentInPackage(startScope.pkg(), name, IndexTree.CLASS, symbols);
|
||||
findIdentInPackage(startScope.pkg(), name, false, symbols);
|
||||
}
|
||||
|
||||
// resolving `receiver.name`
|
||||
private void selectSym(Symbol receiver, @ShortName int name, int kind, Set<Symbol> symbols) throws IncompleteHierarchyException {
|
||||
private void selectSym(Symbol receiver, @ShortName int name, boolean processPackages, Set<Symbol> symbols) throws IncompleteHierarchyException {
|
||||
if (receiver.isPackage())
|
||||
findIdentInPackage((Symbol.PackageSymbol)receiver, name, kind, symbols);
|
||||
findIdentInPackage((Symbol.PackageSymbol)receiver, name, processPackages, symbols);
|
||||
else
|
||||
findMemberType(receiver, name, symbols);
|
||||
}
|
||||
|
||||
private void findIdentInPackage(Symbol.PackageSymbol pck, @ShortName int name, int kind, Set<Symbol> symbols) {
|
||||
private void findIdentInPackage(Symbol.PackageSymbol pck, @ShortName int name, boolean processPackages, Set<Symbol> symbols) {
|
||||
@QNameId int fullname = mySymbols.myNameEnvironment.findExistingName(pck.myQualifiedName, name);
|
||||
if (fullname < 0) {
|
||||
return;
|
||||
}
|
||||
if (BitUtil.isSet(kind, IndexTree.PACKAGE)) {
|
||||
Symbol.PackageSymbol pkg = mySymbols.getPackage(fullname);
|
||||
if (pkg != null)
|
||||
symbols.add(pkg);
|
||||
}
|
||||
if (BitUtil.isSet(kind, IndexTree.CLASS)) {
|
||||
Collections.addAll(symbols, findGlobalType(fullname));
|
||||
if (processPackages) {
|
||||
ContainerUtil.addIfNotNull(symbols, mySymbols.getPackage(fullname));
|
||||
}
|
||||
Collections.addAll(symbols, findGlobalType(fullname));
|
||||
}
|
||||
|
||||
private void findMemberType(Symbol s, @ShortName int name, Set<Symbol> symbols) throws IncompleteHierarchyException {
|
||||
|
||||
@@ -21,9 +21,7 @@ import gnu.trove.TIntHashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Java symbols needed for hierarchy building. Mostly classes ({@link ClassSymbol}) or packages ({@link PackageSymbol}),
|
||||
@@ -200,12 +198,18 @@ public abstract class Symbol {
|
||||
(ClassSymbol[])myMembers;
|
||||
}
|
||||
|
||||
void setMembers(ClassSymbol[] members) {
|
||||
myMembers = members.length == 0 ? null : members.length == 1 ? members[0] : members;
|
||||
void setMembers(List<ClassSymbol> members) {
|
||||
myMembers = members.isEmpty() ? null : members.size() == 1 ? members.get(0) : toSortedArray(members);
|
||||
}
|
||||
|
||||
private static ClassSymbol[] toSortedArray(List<ClassSymbol> members) {
|
||||
ClassSymbol[] array = members.toArray(new ClassSymbol[members.size()]);
|
||||
Arrays.sort(array, CLASS_SYMBOL_BY_NAME_COMPARATOR);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
public static final Comparator<ClassSymbol> CLASS_SYMBOL_BY_NAME_COMPARATOR = (s1, s2) -> {
|
||||
private static final Comparator<ClassSymbol> CLASS_SYMBOL_BY_NAME_COMPARATOR = (s1, s2) -> {
|
||||
int name1 = s1.myShortName;
|
||||
int name2 = s2.myShortName;
|
||||
return (name1 < name2) ? -1 : ((name1 == name2) ? 0 : 1);
|
||||
|
||||
-168
@@ -1,168 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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 com.intellij.psi.impl.java.stubs.index;
|
||||
|
||||
import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree;
|
||||
import com.intellij.util.BitUtil;
|
||||
import com.intellij.util.io.DataExternalizer;
|
||||
import com.intellij.util.io.DataInputOutputUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.intellij.psi.impl.java.stubs.index.JavaUnitDescriptor.ImportFlags.*;
|
||||
|
||||
public class JavaUnitDescriptor implements DataExternalizer<IndexTree.Unit> {
|
||||
public static final JavaUnitDescriptor INSTANCE = new JavaUnitDescriptor();
|
||||
|
||||
private static void writeIntArray(DataOutput out, int[] array) throws IOException {
|
||||
DataInputOutputUtil.writeINT(out, array.length);
|
||||
for (int i : array) {
|
||||
out.writeInt(i);
|
||||
}
|
||||
}
|
||||
private static int[] readIntArray(DataInput in) throws IOException {
|
||||
int length = DataInputOutputUtil.readINT(in);
|
||||
int[] result = new int[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
result[i] = in.readInt();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(@NotNull DataOutput out, IndexTree.Unit value) throws IOException {
|
||||
writeIntArray(out, value.myPackageName);
|
||||
out.writeByte(value.myUnitType);
|
||||
if (value.myUnitType != IndexTree.BYTECODE) {
|
||||
DataInputOutputUtil.writeINT(out, value.imports.length);
|
||||
for (IndexTree.Import anImport : value.imports) {
|
||||
writeImport(out, anImport);
|
||||
}
|
||||
}
|
||||
// class Declaration
|
||||
DataInputOutputUtil.writeINT(out, value.myDecls.length);
|
||||
for (IndexTree.ClassDecl def : value.myDecls) {
|
||||
saveClassDecl(out, def);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveClassDecl(@NotNull DataOutput out, IndexTree.ClassDecl value) throws IOException {
|
||||
DataInputOutputUtil.writeINT(out, value.myStubId);
|
||||
DataInputOutputUtil.writeINT(out, value.myMods);
|
||||
out.writeInt(value.myName);
|
||||
DataInputOutputUtil.writeINT(out, value.mySupers.length);
|
||||
for (int[] aSuper : value.mySupers) {
|
||||
writeIntArray(out, aSuper);
|
||||
}
|
||||
DataInputOutputUtil.writeINT(out, value.myDecls.length);
|
||||
for (IndexTree.Decl def : value.myDecls) {
|
||||
saveDecl(out, def);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveDecl(@NotNull DataOutput out, IndexTree.Decl value) throws IOException {
|
||||
if (value instanceof IndexTree.ClassDecl) {
|
||||
out.writeBoolean(true);
|
||||
saveClassDecl(out, (IndexTree.ClassDecl)value);
|
||||
} else if (value instanceof IndexTree.MemberDecl) {
|
||||
out.writeBoolean(false);
|
||||
IndexTree.MemberDecl memberDecl = (IndexTree.MemberDecl)value;
|
||||
DataInputOutputUtil.writeINT(out, memberDecl.myDecls.length);
|
||||
for (IndexTree.Decl def : memberDecl.myDecls) {
|
||||
saveDecl(out, def);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IndexTree.Unit read(@NotNull DataInput in) throws IOException {
|
||||
int[] pid = readIntArray(in);
|
||||
byte type = in.readByte();
|
||||
IndexTree.Import[] imports = IndexTree.Import.EMPTY_ARRAY;
|
||||
if (type != IndexTree.BYTECODE) {
|
||||
imports = new IndexTree.Import[DataInputOutputUtil.readINT(in)];
|
||||
for (int i = 0; i < imports.length; i++) {
|
||||
imports[i] = readImport(in);
|
||||
}
|
||||
}
|
||||
IndexTree.ClassDecl[] classes = new IndexTree.ClassDecl[DataInputOutputUtil.readINT(in)];
|
||||
for (int i = 0; i < classes.length; i++) {
|
||||
classes[i] = readClassDecl(in);
|
||||
}
|
||||
return new IndexTree.Unit(pid, type, imports, classes);
|
||||
}
|
||||
|
||||
private IndexTree.ClassDecl readClassDecl(DataInput in) throws IOException {
|
||||
int stubId = DataInputOutputUtil.readINT(in);
|
||||
int mods = DataInputOutputUtil.readINT(in);
|
||||
int name = in.readInt();
|
||||
int[][] supers = new int[DataInputOutputUtil.readINT(in)][];
|
||||
for (int i = 0; i < supers.length; i++) {
|
||||
supers[i] = readIntArray(in);
|
||||
}
|
||||
IndexTree.Decl[] decls = new IndexTree.Decl[DataInputOutputUtil.readINT(in)];
|
||||
for (int i = 0; i < decls.length; i++) {
|
||||
decls[i] = readDecl(in);
|
||||
}
|
||||
return new IndexTree.ClassDecl(stubId, mods, name, supers, decls);
|
||||
}
|
||||
|
||||
private IndexTree.Decl readDecl(DataInput in) throws IOException {
|
||||
boolean isClassDecl = in.readBoolean();
|
||||
if (isClassDecl) {
|
||||
return readClassDecl(in);
|
||||
}
|
||||
else {
|
||||
IndexTree.Decl[] decls = new IndexTree.Decl[DataInputOutputUtil.readINT(in)];
|
||||
for (int i = 0; i < decls.length; i++) {
|
||||
decls[i] = readDecl(in);
|
||||
}
|
||||
return new IndexTree.MemberDecl(decls);
|
||||
}
|
||||
}
|
||||
|
||||
interface ImportFlags {
|
||||
int IS_STATIC = 1;
|
||||
int IS_ON_DEMAND = 2;
|
||||
int HAS_ALIAS = 4;
|
||||
}
|
||||
|
||||
private static void writeImport(@NotNull DataOutput out, IndexTree.Import anImport) throws IOException {
|
||||
writeIntArray(out, anImport.myFullname);
|
||||
boolean hasAlias = anImport.myAlias != 0;
|
||||
int flags = 0;
|
||||
flags = BitUtil.set(flags, IS_STATIC, anImport.myStaticImport);
|
||||
flags = BitUtil.set(flags, IS_ON_DEMAND, anImport.myOnDemand);
|
||||
flags = BitUtil.set(flags, HAS_ALIAS, hasAlias);
|
||||
out.writeByte(flags);
|
||||
if (hasAlias) {
|
||||
out.writeInt(anImport.myAlias);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static IndexTree.Import readImport(@NotNull DataInput in) throws IOException {
|
||||
int[] fullname = readIntArray(in);
|
||||
int flags = in.readByte();
|
||||
return new IndexTree.Import(fullname,
|
||||
BitUtil.isSet(flags, IS_STATIC), BitUtil.isSet(flags, IS_ON_DEMAND),
|
||||
BitUtil.isSet(flags, HAS_ALIAS) ? in.readInt() : 0);
|
||||
}
|
||||
|
||||
}
|
||||
+26
-12
@@ -848,10 +848,12 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase {
|
||||
|
||||
public void testLineMarkersClearWhenTypingAtTheEndOfPsiComment() throws Throwable {
|
||||
configureByText(JavaFileType.INSTANCE, "class S {\n//ddd<caret>\n}");
|
||||
StringBuffer log = new StringBuffer();
|
||||
final LineMarkerProvider provider = new LineMarkerProvider() {
|
||||
@Nullable
|
||||
@Override
|
||||
public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
|
||||
log.append("getLineMarkerInfo(" + element + ")\n");
|
||||
if (element instanceof PsiComment) {
|
||||
return new LineMarkerInfo<>((PsiComment)element, element.getTextRange(), null, Pass.UPDATE_ALL, null, null,
|
||||
GutterIconRenderer.Alignment.LEFT);
|
||||
@@ -867,22 +869,34 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase {
|
||||
LineMarkerProviders.INSTANCE.addExplicitExtension(JavaLanguage.INSTANCE, provider);
|
||||
Disposer.register(myTestRootDisposable, () -> LineMarkerProviders.INSTANCE.removeExplicitExtension(JavaLanguage.INSTANCE, provider));
|
||||
|
||||
assertEmpty(highlightErrors());
|
||||
try {
|
||||
List<HighlightInfo> infos = highlightErrors();
|
||||
log.append("infos: " + infos + "\n");
|
||||
assertEmpty(infos);
|
||||
|
||||
List<LineMarkerInfo> lineMarkers = DaemonCodeAnalyzerImpl.getLineMarkers(myEditor.getDocument(), getProject());
|
||||
assertOneElement(lineMarkers);
|
||||
List<LineMarkerInfo> lineMarkers = DaemonCodeAnalyzerImpl.getLineMarkers(myEditor.getDocument(), getProject());
|
||||
assertOneElement(lineMarkers);
|
||||
|
||||
type(' ');
|
||||
assertEmpty(highlightErrors());
|
||||
type(' ');
|
||||
infos = highlightErrors();
|
||||
log.append("infos: " + infos + "\n");
|
||||
assertEmpty(infos);
|
||||
|
||||
lineMarkers = DaemonCodeAnalyzerImpl.getLineMarkers(myEditor.getDocument(), getProject());
|
||||
assertOneElement(lineMarkers);
|
||||
lineMarkers = DaemonCodeAnalyzerImpl.getLineMarkers(myEditor.getDocument(), getProject());
|
||||
assertOneElement(lineMarkers);
|
||||
|
||||
backspace();
|
||||
assertEmpty(highlightErrors());
|
||||
backspace();
|
||||
infos = highlightErrors();
|
||||
log.append("infos: " + infos + "\n");
|
||||
assertEmpty(infos);
|
||||
|
||||
lineMarkers = DaemonCodeAnalyzerImpl.getLineMarkers(myEditor.getDocument(), getProject());
|
||||
assertOneElement(lineMarkers);
|
||||
lineMarkers = DaemonCodeAnalyzerImpl.getLineMarkers(myEditor.getDocument(), getProject());
|
||||
assertOneElement(lineMarkers);
|
||||
}
|
||||
catch (AssertionError e) {
|
||||
System.err.println("Log:\n"+log);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public void testWhenTypingOverWrongReferenceItsColorChangesToBlackAndOnlyAfterHighlightingFinishedItReturnsToRed() throws Throwable {
|
||||
@@ -1533,7 +1547,6 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase {
|
||||
}
|
||||
|
||||
public void testReactivityPerformance() throws Throwable {
|
||||
List<Thread> watchers = new ArrayList<>();
|
||||
@NonNls String filePath = "/psi/resolve/Thinlet.java";
|
||||
configureByFile(filePath);
|
||||
type(' ');
|
||||
@@ -1547,6 +1560,7 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase {
|
||||
int N = Math.max(5, Timings.adjustAccordingToMySpeed(80, true));
|
||||
System.out.println("N = " + N);
|
||||
final long[] interruptTimes = new long[N];
|
||||
List<Thread> watchers = new ArrayList<>();
|
||||
for (int i = 0; i < N; i++) {
|
||||
codeAnalyzer.restart();
|
||||
final int finalI = i;
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import org.apache.log4j.PropertyConfigurator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.api.GlobalOptions;
|
||||
|
||||
import java.io.*;
|
||||
@@ -83,8 +84,9 @@ public class LogSetup {
|
||||
}
|
||||
|
||||
private static class MyLoggerFactory implements Logger.Factory {
|
||||
@NotNull
|
||||
@Override
|
||||
public Logger getLoggerInstance(String category) {
|
||||
public Logger getLoggerInstance(@NotNull String category) {
|
||||
return new Log4jBasedLogger(org.apache.log4j.Logger.getLogger(category));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,8 +406,9 @@ public class JpsGantProjectBuilder {
|
||||
private static AntMessageHandler ourMessageHandler;
|
||||
private static Logger.Factory ourFileLoggerFactory;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Logger getLoggerInstance(String category) {
|
||||
public Logger getLoggerInstance(@NotNull String category) {
|
||||
DefaultLogger antLogger = new DefaultLogger(category) {
|
||||
@Override
|
||||
public void error(@NonNls String message, @Nullable Throwable t, @NotNull @NonNls String... details) {
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.apache.log4j.Level;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.log4j.PatternLayout;
|
||||
import org.apache.log4j.RollingFileAppender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -42,8 +43,9 @@ public class Log4jFileLoggerFactory implements com.intellij.openapi.diagnostic.L
|
||||
myAppender.setMaxBackupIndex(10);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public com.intellij.openapi.diagnostic.Logger getLoggerInstance(String category) {
|
||||
public com.intellij.openapi.diagnostic.Logger getLoggerInstance(@NotNull String category) {
|
||||
final Logger logger = Logger.getLogger(category);
|
||||
logger.addAppender(myAppender);
|
||||
logger.setLevel(isDebugLevel(category) ? Level.DEBUG : Level.INFO);
|
||||
|
||||
@@ -41,6 +41,10 @@ public class JsonSchemaFileTypeManager implements ProjectManagerListener {
|
||||
return ServiceManager.getService(JsonSchemaFileTypeManager.class);
|
||||
}
|
||||
|
||||
public JsonSchemaFileTypeManager() {
|
||||
ProjectManager.getInstance().addProjectManagerListener(this);
|
||||
}
|
||||
|
||||
public boolean isJsonSchemaFile(@NotNull final VirtualFile file) {
|
||||
ensureInitialized();
|
||||
for (Collection<VirtualFile> files : myFileSets.values()) {
|
||||
|
||||
@@ -57,7 +57,7 @@ public class ProblemDescriptorUtil {
|
||||
}
|
||||
ref = StringUtil.replaceChar(ref, '\n', ' ').trim();
|
||||
ref = StringUtil.first(ref, 100, true);
|
||||
return ref;
|
||||
return clearDuplicatedWhitespaces(ref);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -181,4 +181,40 @@ public class ProblemDescriptorUtil {
|
||||
}
|
||||
throw new RuntimeException("Cannot map " + highlightType);
|
||||
}
|
||||
|
||||
static String clearDuplicatedWhitespaces(@NotNull String input) {
|
||||
if (input.isEmpty()) {
|
||||
return input;
|
||||
}
|
||||
char[] refWithoutRedundantSpaces = null;
|
||||
int tail = 0;
|
||||
for (int i = 0; i < input.length() - 1; i++) {
|
||||
final char c1 = input.charAt(i);
|
||||
final char c2 = input.charAt(i+1);
|
||||
final boolean isWhiteSpace1 = StringUtil.isWhiteSpace(c1);
|
||||
final boolean isWhiteSpace2 = StringUtil.isWhiteSpace(c2);
|
||||
if (isWhiteSpace1 && isWhiteSpace2) {
|
||||
if (refWithoutRedundantSpaces == null) {
|
||||
refWithoutRedundantSpaces = new char[input.length()];
|
||||
for (int j = 0; j < i; j++) {
|
||||
refWithoutRedundantSpaces[j] = input.charAt(j);
|
||||
}
|
||||
tail = i;
|
||||
}
|
||||
}
|
||||
else if (refWithoutRedundantSpaces != null) {
|
||||
refWithoutRedundantSpaces[tail++] = isWhiteSpace1 ? ' ' : c1;
|
||||
}
|
||||
}
|
||||
final char lastChar = input.charAt(input.length() - 1);
|
||||
final boolean isLastWhiteSpace = StringUtil.isWhiteSpace(lastChar);
|
||||
if (refWithoutRedundantSpaces != null) {
|
||||
if (!isLastWhiteSpace) {
|
||||
refWithoutRedundantSpaces[tail++] = lastChar;
|
||||
}
|
||||
} else if (isLastWhiteSpace) {
|
||||
return new String(input.toCharArray(), 0, input.length() - 1);
|
||||
}
|
||||
return refWithoutRedundantSpaces == null ? input : new String(refWithoutRedundantSpaces, 0, tail);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,10 +40,7 @@ import com.intellij.pom.event.PomModelEvent;
|
||||
import com.intellij.pom.impl.PomTransactionBase;
|
||||
import com.intellij.pom.tree.TreeAspect;
|
||||
import com.intellij.pom.tree.TreeAspectEvent;
|
||||
import com.intellij.psi.FileViewProvider;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiLock;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.impl.source.PsiFileImpl;
|
||||
import com.intellij.psi.impl.source.text.DiffLog;
|
||||
@@ -182,6 +179,9 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
|
||||
if (!project.isInitialized()) return;
|
||||
PsiFile psiFile = PsiDocumentManager.getInstance(project).getCachedPsiFile(document);
|
||||
if (psiFile == null) return;
|
||||
if (psiFile instanceof PsiCompiledFile) {
|
||||
throw new IllegalArgumentException("Can't commit ClsFile: "+psiFile);
|
||||
}
|
||||
|
||||
doQueue(project, document, getAllFileNodes(psiFile), reason, currentModalityState);
|
||||
}
|
||||
|
||||
@@ -42,14 +42,11 @@ import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageManagerImpl;
|
||||
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.FunctionUtil;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
@@ -97,7 +94,7 @@ public class LineMarkersPass extends TextEditorHighlightingPass implements LineM
|
||||
|
||||
@Override
|
||||
public void doCollectInformation(@NotNull ProgressIndicator progress) {
|
||||
final List<LineMarkerInfo> lineMarkers = new ArrayList<LineMarkerInfo>();
|
||||
final List<LineMarkerInfo> lineMarkers = new ArrayList<>();
|
||||
final FileViewProvider viewProvider = myFile.getViewProvider();
|
||||
final Set<Language> relevantLanguages = viewProvider.getLanguages();
|
||||
for (Language language : relevantLanguages) {
|
||||
@@ -115,8 +112,9 @@ public class LineMarkersPass extends TextEditorHighlightingPass implements LineM
|
||||
myMarkers = mergeLineMarkers(lineMarkers, myEditor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static List<LineMarkerInfo> mergeLineMarkers(@NotNull List<LineMarkerInfo> markers, @Nullable Editor editor) {
|
||||
List<MergeableLineMarkerInfo> forMerge = new ArrayList<MergeableLineMarkerInfo>();
|
||||
List<MergeableLineMarkerInfo> forMerge = new ArrayList<>();
|
||||
final Iterator<LineMarkerInfo> iterator = markers.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final LineMarkerInfo marker = iterator.next();
|
||||
@@ -129,13 +127,13 @@ public class LineMarkersPass extends TextEditorHighlightingPass implements LineM
|
||||
|
||||
if (forMerge.isEmpty() || editor == null) return markers;
|
||||
|
||||
final List<LineMarkerInfo> result = new ArrayList<LineMarkerInfo>(markers);
|
||||
TIntObjectHashMap<List<MergeableLineMarkerInfo>> sameLineMarkers = new TIntObjectHashMap<List<MergeableLineMarkerInfo>>();
|
||||
List<LineMarkerInfo> result = new ArrayList<>(markers);
|
||||
TIntObjectHashMap<List<MergeableLineMarkerInfo>> sameLineMarkers = new TIntObjectHashMap<>();
|
||||
for (MergeableLineMarkerInfo info : forMerge) {
|
||||
int line = editor.getDocument().getLineNumber(info.startOffset);
|
||||
List<MergeableLineMarkerInfo> infos = sameLineMarkers.get(line);
|
||||
if (infos == null) {
|
||||
infos = new ArrayList<MergeableLineMarkerInfo>();
|
||||
infos = new ArrayList<>();
|
||||
sameLineMarkers.put(line, infos);
|
||||
}
|
||||
infos.add(info);
|
||||
@@ -149,14 +147,13 @@ public class LineMarkersPass extends TextEditorHighlightingPass implements LineM
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<LineMarkerProvider> getMarkerProviders(@NotNull Language language, @NotNull final Project project) {
|
||||
List<LineMarkerProvider> forLanguage = LineMarkerProviders.INSTANCE.allForLanguageOrAny(language);
|
||||
List<LineMarkerProvider> providers = DumbService.getInstance(project).filterByDumbAwareness(forLanguage);
|
||||
final LineMarkerSettings settings = LineMarkerSettings.getSettings();
|
||||
return ContainerUtil.filter(providers, provider -> {
|
||||
if (!(provider instanceof LineMarkerProviderDescriptor)) return true;
|
||||
return settings.isEnabled((LineMarkerProviderDescriptor)provider);
|
||||
});
|
||||
return ContainerUtil.filter(providers, provider -> !(provider instanceof LineMarkerProviderDescriptor)
|
||||
|| settings.isEnabled((LineMarkerProviderDescriptor)provider));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -177,10 +174,7 @@ public class LineMarkersPass extends TextEditorHighlightingPass implements LineM
|
||||
try {
|
||||
info = provider.getLineMarkerInfo(element);
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (IndexNotReadyException e) {
|
||||
catch (ProcessCanceledException | IndexNotReadyException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e) {
|
||||
@@ -200,19 +194,14 @@ public class LineMarkersPass extends TextEditorHighlightingPass implements LineM
|
||||
@NotNull final PsiFile file,
|
||||
@NotNull final ProgressIndicator progress) {
|
||||
final InjectedLanguageManager manager = InjectedLanguageManager.getInstance(file.getProject());
|
||||
final List<LineMarkerInfo> injectedMarkers = new ArrayList<LineMarkerInfo>();
|
||||
|
||||
final Set<PsiFile> injectedFiles = new THashSet<PsiFile>();
|
||||
final PsiLanguageInjectionHost.InjectedPsiVisitor collectingVisitor = new PsiLanguageInjectionHost.InjectedPsiVisitor() {
|
||||
@Override
|
||||
public void visit(@NotNull final PsiFile injectedPsi, @NotNull List<PsiLanguageInjectionHost.Shred> places) {
|
||||
injectedFiles.add(injectedPsi);
|
||||
}
|
||||
};
|
||||
final Set<PsiFile> injectedFiles = new THashSet<>();
|
||||
final PsiLanguageInjectionHost.InjectedPsiVisitor collectingVisitor = (injectedPsi, places) -> injectedFiles.add(injectedPsi);
|
||||
InjectedLanguageManagerImpl.getInstanceImpl(file.getProject()).processInjectableElements(elements, element -> {
|
||||
InjectedLanguageUtil.enumerate(element, file, false, collectingVisitor);
|
||||
return true;
|
||||
});
|
||||
final List<LineMarkerInfo> injectedMarkers = new ArrayList<>();
|
||||
for (PsiFile injectedPsi : injectedFiles) {
|
||||
final Project project = injectedPsi.getProject();
|
||||
Document document = PsiDocumentManager.getInstance(project).getCachedDocument(injectedPsi);
|
||||
@@ -228,8 +217,9 @@ public class LineMarkersPass extends TextEditorHighlightingPass implements LineM
|
||||
TextRange hostRange = manager.injectedToHost(injectedPsi, editable);
|
||||
Icon icon = gutterRenderer == null ? null : gutterRenderer.getIcon();
|
||||
LineMarkerInfo<PsiElement> converted =
|
||||
new LineMarkerInfo<PsiElement>(injectedMarker.getElement(), hostRange, icon, injectedMarker.updatePass,
|
||||
element -> injectedMarker.getLineMarkerTooltip(), injectedMarker.getNavigationHandler(), GutterIconRenderer.Alignment.RIGHT);
|
||||
new LineMarkerInfo<>(injectedMarker.getElement(), hostRange, icon, injectedMarker.updatePass,
|
||||
element -> injectedMarker.getLineMarkerTooltip(), injectedMarker.getNavigationHandler(),
|
||||
GutterIconRenderer.Alignment.RIGHT);
|
||||
result.add(converted);
|
||||
}
|
||||
}
|
||||
@@ -250,13 +240,13 @@ public class LineMarkersPass extends TextEditorHighlightingPass implements LineM
|
||||
|
||||
@NotNull
|
||||
public static LineMarkerInfo createMethodSeparatorLineMarker(@NotNull PsiElement startFrom, @NotNull EditorColorsManager colorsManager) {
|
||||
LineMarkerInfo info = new LineMarkerInfo<PsiElement>(
|
||||
startFrom,
|
||||
startFrom.getTextRange(),
|
||||
null,
|
||||
Pass.UPDATE_ALL,
|
||||
LineMarkerInfo info = new LineMarkerInfo<>(
|
||||
startFrom,
|
||||
startFrom.getTextRange(),
|
||||
null,
|
||||
Pass.UPDATE_ALL,
|
||||
FunctionUtil.<Object, String>nullConstant(),
|
||||
null,
|
||||
null,
|
||||
GutterIconRenderer.Alignment.RIGHT
|
||||
);
|
||||
EditorColorsScheme scheme = colorsManager.getGlobalScheme();
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.util.List;
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
@FunctionalInterface
|
||||
interface LineMarkersProcessor {
|
||||
void addLineMarkers(@NotNull List<PsiElement> elements,
|
||||
@NotNull List<LineMarkerProvider> providers,
|
||||
|
||||
+1
-1
@@ -120,7 +120,7 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
|
||||
myTreeState = treeState;
|
||||
}
|
||||
|
||||
public synchronized void addView(@NotNull InspectionResultsView view,
|
||||
public void addView(@NotNull InspectionResultsView view,
|
||||
@NotNull String title,
|
||||
boolean isOffline) {
|
||||
LOG.assertTrue(myContent == null, "GlobalInspectionContext is busy under other view now");
|
||||
|
||||
@@ -86,8 +86,9 @@ public class GotoActionItemProvider implements ChooseByNameItemProvider {
|
||||
private boolean processAbbreviations(final String pattern, Processor<MatchedValue> consumer, DataContext context) {
|
||||
List<String> actionIds = AbbreviationManager.getInstance().findActions(pattern);
|
||||
JBIterable<MatchedValue> wrappers = JBIterable.from(actionIds)
|
||||
.transform(actionId -> {
|
||||
AnAction action = myActionManager.getAction(actionId);
|
||||
.transform(myActionManager::getAction)
|
||||
.filter(Condition.NOT_NULL)
|
||||
.transform(action -> {
|
||||
ActionWrapper wrapper = new ActionWrapper(action, myModel.myActionGroups.get(action), MatchMode.NAME, context);
|
||||
return new MatchedValue(wrapper, pattern) {
|
||||
@Nullable
|
||||
|
||||
@@ -21,6 +21,8 @@ import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
|
||||
import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory;
|
||||
import com.intellij.openapi.editor.impl.SettingsImpl;
|
||||
import com.intellij.openapi.editor.impl.softwrap.SoftWrapAppliancePlaces;
|
||||
import com.intellij.openapi.editor.markup.HighlighterLayer;
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
@@ -136,10 +138,14 @@ public class DetailViewImpl extends JPanel implements DetailView, UserDataHolder
|
||||
((EditorEx)getEditor()).setFile(file);
|
||||
((EditorEx)getEditor()).setHighlighter(highlighter);
|
||||
|
||||
getEditor().getSettings().setAnimatedScrolling(false);
|
||||
getEditor().getSettings().setRefrainFromScrolling(false);
|
||||
getEditor().getSettings().setLineNumbersShown(true);
|
||||
getEditor().getSettings().setFoldingOutlineShown(false);
|
||||
EditorSettings settings = getEditor().getSettings();
|
||||
settings.setAnimatedScrolling(false);
|
||||
settings.setRefrainFromScrolling(false);
|
||||
settings.setLineNumbersShown(true);
|
||||
settings.setFoldingOutlineShown(false);
|
||||
if (settings instanceof SettingsImpl) {
|
||||
((SettingsImpl)settings).setSoftWrapAppliancePlace(SoftWrapAppliancePlaces.PREVIEW);
|
||||
}
|
||||
((EditorEx)getEditor()).getFoldingModel().setFoldingEnabled(false);
|
||||
|
||||
add(getEditor().getComponent(), BorderLayout.CENTER);
|
||||
|
||||
@@ -40,7 +40,7 @@ import java.io.LineNumberReader;
|
||||
/**
|
||||
* @author Mike
|
||||
*/
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
@SuppressWarnings("HardCodedStringLiteral")
|
||||
public class IdeaLogger extends Log4jBasedLogger {
|
||||
private static ApplicationInfoProvider ourApplicationInfoProvider = getIdeaInfoProvider();
|
||||
|
||||
@@ -53,11 +53,11 @@ public class IdeaLogger extends Log4jBasedLogger {
|
||||
return ourCompilationTimestamp;
|
||||
}
|
||||
|
||||
private static String ourCompilationTimestamp;
|
||||
private static final String ourCompilationTimestamp;
|
||||
|
||||
@NonNls private static final String COMPILATION_TIMESTAMP_RESOURCE_NAME = "/.compilation-timestamp";
|
||||
|
||||
private static ThrowableRenderer ourThrowableRenderer = t -> {
|
||||
private static final ThrowableRenderer ourThrowableRenderer = t -> {
|
||||
String[] defaultRes = DefaultThrowableRenderer.render(t);
|
||||
int maxStackSize = 1024;
|
||||
int maxExtraSize = 256;
|
||||
@@ -73,24 +73,22 @@ public class IdeaLogger extends Log4jBasedLogger {
|
||||
|
||||
static {
|
||||
InputStream stream = Logger.class.getResourceAsStream(COMPILATION_TIMESTAMP_RESOURCE_NAME);
|
||||
String stamp = null;
|
||||
if (stream != null) {
|
||||
try {
|
||||
LineNumberReader reader = new LineNumberReader(new InputStreamReader(stream));
|
||||
try {
|
||||
try (LineNumberReader reader = new LineNumberReader(new InputStreamReader(stream))) {
|
||||
String s = reader.readLine();
|
||||
if (s != null) {
|
||||
ourCompilationTimestamp = s.trim();
|
||||
stamp = s.trim();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
catch (IOException ignored) { }
|
||||
}
|
||||
ourCompilationTimestamp = stamp;
|
||||
}
|
||||
|
||||
IdeaLogger(org.apache.log4j.Logger logger) {
|
||||
IdeaLogger(@NotNull org.apache.log4j.Logger logger) {
|
||||
super(logger);
|
||||
LoggerRepository repository = myLogger.getLoggerRepository();
|
||||
if (repository instanceof ThrowableRendererSupport) {
|
||||
@@ -109,7 +107,7 @@ public class IdeaLogger extends Log4jBasedLogger {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(@NonNls String message, Attachment... attachments) {
|
||||
public void error(@NonNls String message, @NotNull Attachment... attachments) {
|
||||
myLogger.error(LogMessageEx.createEvent(message, DebugUtil.currentStackTrace(), attachments));
|
||||
}
|
||||
|
||||
@@ -170,21 +168,20 @@ public class IdeaLogger extends Log4jBasedLogger {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ThrowableRenderer getThrowableRenderer() {
|
||||
return ourThrowableRenderer;
|
||||
}
|
||||
|
||||
public static void setApplicationInfoProvider(ApplicationInfoProvider aProvider) {
|
||||
public static void setApplicationInfoProvider(@NotNull ApplicationInfoProvider aProvider) {
|
||||
ourApplicationInfoProvider = aProvider;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ApplicationInfoProvider getIdeaInfoProvider() {
|
||||
return new ApplicationInfoProvider() {
|
||||
@Override
|
||||
public String getInfo() {
|
||||
final ApplicationInfoEx info = ApplicationInfoImpl.getShadowInstance();
|
||||
return info.getFullApplicationName() + " " + "Build #" + info.getBuild().asString();
|
||||
}
|
||||
return () -> {
|
||||
final ApplicationInfoEx info = ApplicationInfoImpl.getShadowInstance();
|
||||
return info.getFullApplicationName() + " " + "Build #" + info.getBuild().asString();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.xml.DOMConfigurator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.StringReader;
|
||||
@@ -35,8 +36,9 @@ public class LoggerFactory implements Logger.Factory {
|
||||
|
||||
private LoggerFactory() { }
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public synchronized Logger getLoggerInstance(String name) {
|
||||
public synchronized Logger getLoggerInstance(@NotNull String name) {
|
||||
try {
|
||||
if (!myInitialized) {
|
||||
init();
|
||||
|
||||
+1
-2
@@ -130,8 +130,7 @@ public class EditorComponentImpl extends JTextComponent implements Scrollable, D
|
||||
if (myEditor.isDisposed() || myEditor.isRendererMode()) return null;
|
||||
|
||||
if (CommonDataKeys.EDITOR.is(dataId)) {
|
||||
// for 'big' editors return null to allow injected editors (see com.intellij.openapi.fileEditor.impl.text.TextEditorComponent.getData())
|
||||
return myEditor.getVirtualFile() == null ? myEditor : null;
|
||||
return myEditor;
|
||||
}
|
||||
if (CommonDataKeys.CARET.is(dataId)) {
|
||||
return myEditor.getCaretModel().getCurrentCaret();
|
||||
|
||||
@@ -5726,8 +5726,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
|
||||
private class MyMouseAdapter extends MouseAdapter {
|
||||
private boolean mySelectionTweaked;
|
||||
|
||||
@Override
|
||||
public void mousePressed(@NotNull MouseEvent e) {
|
||||
requestFocus();
|
||||
@@ -5769,7 +5767,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
clearDraggedRange();
|
||||
|
||||
|
||||
mySelectionTweaked = false;
|
||||
myMousePressedEvent = e;
|
||||
EditorMouseEvent event = new EditorMouseEvent(EditorImpl.this, e, getMouseEventArea(e));
|
||||
|
||||
@@ -5827,9 +5824,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
myMultiSelectionInProgress = false;
|
||||
|
||||
myDragOnGutterSelectionStartLine = -1;
|
||||
if (!mySelectionTweaked) {
|
||||
tweakSelectionIfNecessary(e);
|
||||
}
|
||||
if (e.isConsumed()) {
|
||||
return;
|
||||
}
|
||||
@@ -5929,10 +5923,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
if (eventArea == EditorMouseEventArea.LINE_MARKERS_AREA ||
|
||||
eventArea == EditorMouseEventArea.ANNOTATIONS_AREA ||
|
||||
eventArea == EditorMouseEventArea.LINE_NUMBERS_AREA) {
|
||||
if (tweakSelectionIfNecessary(e)) {
|
||||
mySelectionTweaked = true;
|
||||
}
|
||||
else {
|
||||
if (!tweakSelectionIfNecessary(e)) {
|
||||
myGutterComponent.mousePressed(e);
|
||||
}
|
||||
if (e.isConsumed()) return false;
|
||||
|
||||
@@ -707,11 +707,17 @@ class EditorPainter implements TextDrawingCallback {
|
||||
float startX = ranges.get(i);
|
||||
float endX = ranges.get(i + 1);
|
||||
if (startX == endX) {
|
||||
endX++;
|
||||
if (startX > 0) {
|
||||
startX--;
|
||||
}
|
||||
else {
|
||||
endX++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
endX--;
|
||||
}
|
||||
ranges.set(i, startX);
|
||||
ranges.set(i + 1, endX);
|
||||
}
|
||||
return ranges;
|
||||
|
||||
@@ -30,11 +30,14 @@ public class ProjectRootUtil {
|
||||
|
||||
if (scope.contains(forFile)) return forFile;
|
||||
|
||||
VirtualFile canonicalForFile = forFile.getCanonicalFile();
|
||||
if (canonicalForFile == null) canonicalForFile = forFile;
|
||||
|
||||
Collection<VirtualFile> projectFiles =
|
||||
FilenameIndex.getVirtualFilesByName(project, forFile.getName(), true, scope);
|
||||
FilenameIndex.getVirtualFilesByName(project, canonicalForFile.getName(), true, scope);
|
||||
|
||||
for (VirtualFile eachContentFile : projectFiles) {
|
||||
if (forFile.equals(eachContentFile.getCanonicalFile())) return eachContentFile;
|
||||
if (canonicalForFile.equals(eachContentFile.getCanonicalFile())) return eachContentFile;
|
||||
}
|
||||
|
||||
return forFile;
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.intellij.util.ui.table;
|
||||
|
||||
import com.intellij.util.ui.EditableModel;
|
||||
|
||||
import javax.swing.event.TableModelEvent;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.TableModel;
|
||||
|
||||
@@ -28,6 +29,13 @@ public abstract class JBListTableModel extends AbstractTableModel implements Edi
|
||||
|
||||
public JBListTableModel(TableModel model) {
|
||||
myModel = model;
|
||||
myModel.addTableModelListener(e ->
|
||||
fireTableChanged(
|
||||
new TableModelEvent(
|
||||
this, e.getFirstRow(), e.getLastRow(), e.getColumn(), e.getType()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -63,18 +71,13 @@ public abstract class JBListTableModel extends AbstractTableModel implements Edi
|
||||
for (int i = 0; i < myModel.getColumnCount(); i++) {
|
||||
myModel.setValueAt(((JBTableRow)value).getValueAt(i), row, i);
|
||||
}
|
||||
fireTableCellUpdated(row, column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRow() {
|
||||
final int count = myModel.getRowCount();
|
||||
if (myModel instanceof EditableModel) {
|
||||
((EditableModel)myModel).addRow();
|
||||
}
|
||||
if (count < myModel.getRowCount()) {
|
||||
fireTableRowsInserted(count, myModel.getRowCount() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,7 +85,6 @@ public abstract class JBListTableModel extends AbstractTableModel implements Edi
|
||||
if (myModel instanceof EditableModel) {
|
||||
((EditableModel)myModel).removeRow(index);
|
||||
}
|
||||
fireTableRowsDeleted(index, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,6 +100,5 @@ public abstract class JBListTableModel extends AbstractTableModel implements Edi
|
||||
if (myModel instanceof EditableModel) {
|
||||
((EditableModel)myModel).exchangeRows(oldIndex, newIndex);
|
||||
}
|
||||
fireTableRowsUpdated(Math.min(oldIndex, newIndex), Math.max(oldIndex, newIndex));
|
||||
}
|
||||
}
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInspection;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class ProblemDescriptorUtilTest {
|
||||
|
||||
@Test
|
||||
public void testClearDuplicatedWhiteSpaces() {
|
||||
assertEquals("", ProblemDescriptorUtil.clearDuplicatedWhitespaces(""));
|
||||
assertEquals("some text is here", ProblemDescriptorUtil.clearDuplicatedWhitespaces("some text is here"));
|
||||
assertEquals("some text is here", ProblemDescriptorUtil.clearDuplicatedWhitespaces("some text is here "));
|
||||
assertEquals("some text is here", ProblemDescriptorUtil.clearDuplicatedWhitespaces("some text is here "));
|
||||
assertEquals("some text is here", ProblemDescriptorUtil.clearDuplicatedWhitespaces("some \t\t text\tis\t\t\t\t\there"));
|
||||
assertEquals("sometextishere", ProblemDescriptorUtil.clearDuplicatedWhitespaces("sometextishere"));
|
||||
}
|
||||
}
|
||||
@@ -405,4 +405,11 @@ public class EditorImplTest extends AbstractEditorTest {
|
||||
assertEquals(7, highlighters[0].getStartOffset());
|
||||
assertEquals(8, highlighters[0].getEndOffset());
|
||||
}
|
||||
|
||||
public void testShiftPressedBeforeDragOverLineNumbersIsFinished() throws Exception {
|
||||
initText("abc\ndef\nghi");
|
||||
EditorTestUtil.setEditorVisibleSize(myEditor, 1000, 1000); // enable drag testing
|
||||
mouse().pressAtLineNumbers(0).dragToLineNumbers(2).shift().release();
|
||||
checkResultByText("<selection>abc\ndef\nghi</selection>");
|
||||
}
|
||||
}
|
||||
|
||||
+47
-28
@@ -30,9 +30,10 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ProjectRootUtilSymlinkedFilesTest extends PlatformTestCase {
|
||||
private File myCanonicalDir;
|
||||
private File myCanonicalFile;
|
||||
private VirtualFile myCanonicalVFile;
|
||||
private File myNonContentDir;
|
||||
private File myNonContentFile;
|
||||
private VirtualFile myNonContentVFile;
|
||||
|
||||
private File myContentDir;
|
||||
private VirtualFile myContentVDir;
|
||||
private File myLibraryDir;
|
||||
@@ -46,12 +47,12 @@ public class ProjectRootUtilSymlinkedFilesTest extends PlatformTestCase {
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myCanonicalDir = FileUtil.createTempDirectory("canonical", null);
|
||||
myCanonicalFile = new File(myCanonicalDir, "foo.txt");
|
||||
assertTrue(myCanonicalFile.createNewFile());
|
||||
myNonContentDir = FileUtil.createTempDirectory("nonContent", null);
|
||||
myNonContentFile = new File(myNonContentDir, "foo.txt");
|
||||
assertTrue(myNonContentFile.createNewFile());
|
||||
|
||||
myCanonicalVFile = VfsUtil.findFileByIoFile(myCanonicalFile, true);
|
||||
assertNotNull(myCanonicalVFile);
|
||||
myNonContentVFile = VfsUtil.findFileByIoFile(myNonContentFile, true);
|
||||
assertNotNull(myNonContentVFile);
|
||||
|
||||
myContentDir = FileUtil.createTempDirectory("content", null);
|
||||
myContentVDir = VfsUtil.findFileByIoFile(myContentDir, true);
|
||||
@@ -65,7 +66,7 @@ public class ProjectRootUtilSymlinkedFilesTest extends PlatformTestCase {
|
||||
}
|
||||
|
||||
public void testNoFilesInContent() throws Exception {
|
||||
assertEquals(myCanonicalVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myCanonicalVFile));
|
||||
assertEquals(myNonContentVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myNonContentVFile));
|
||||
}
|
||||
|
||||
public void testLinkedDirInContent() throws Exception {
|
||||
@@ -78,48 +79,48 @@ public class ProjectRootUtilSymlinkedFilesTest extends PlatformTestCase {
|
||||
|
||||
public void doTestLinkedDirInProjectRoots(boolean content) throws Exception {
|
||||
String linkedPath = (content ? myContentDir : myLibraryDir).getPath() + "/linked";
|
||||
IoTestUtil.createSymLink(myCanonicalDir.getPath(), linkedPath, true);
|
||||
IoTestUtil.createSymLink(myNonContentDir.getPath(), linkedPath, true);
|
||||
|
||||
VirtualFile linkedVFile = VfsUtil.findFileByIoFile(new File(linkedPath, myCanonicalFile.getName()), true);
|
||||
VirtualFile linkedVFile = VfsUtil.findFileByIoFile(new File(linkedPath, myNonContentFile.getName()), true);
|
||||
|
||||
assertEquals(linkedVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myCanonicalVFile));
|
||||
assertEquals(linkedVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myNonContentVFile));
|
||||
}
|
||||
|
||||
// not supported
|
||||
public void _testLinkedFileInSources() throws Exception {
|
||||
String linkedPath = myContentDir.getPath() + "/linked.txt";
|
||||
IoTestUtil.createSymLink(myCanonicalVFile.getPath(), linkedPath, true);
|
||||
IoTestUtil.createSymLink(myNonContentVFile.getPath(), linkedPath, true);
|
||||
|
||||
VirtualFile linkedVFile = VfsUtil.findFileByIoFile(new File(linkedPath), true);
|
||||
assertEquals(linkedVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myCanonicalVFile));
|
||||
assertEquals(linkedVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myNonContentVFile));
|
||||
}
|
||||
|
||||
public void testFileWithTheSameNotButNotLinked() throws Exception {
|
||||
new WriteAction<Object>() {
|
||||
@Override
|
||||
protected void run(@NotNull Result<Object> result) throws Throwable {
|
||||
myContentVDir.createChildData(this, myCanonicalFile.getName());
|
||||
myContentVDir.createChildData(this, myNonContentFile.getName());
|
||||
}
|
||||
}.execute();
|
||||
|
||||
assertEquals(myCanonicalVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myCanonicalVFile));
|
||||
assertEquals(myNonContentVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myNonContentVFile));
|
||||
}
|
||||
|
||||
public void testWhenSeveralLinkedAlwaysReturnTheSameFile() throws Exception {
|
||||
String linkedPath1 = myContentDir.getPath() + "/linked1";
|
||||
IoTestUtil.createSymLink(myCanonicalDir.getPath(), linkedPath1, true);
|
||||
VirtualFile linkedVFile1 = VfsUtil.findFileByIoFile(new File(linkedPath1, myCanonicalFile.getName()), true);
|
||||
IoTestUtil.createSymLink(myNonContentDir.getPath(), linkedPath1, true);
|
||||
VirtualFile linkedVFile1 = VfsUtil.findFileByIoFile(new File(linkedPath1, myNonContentFile.getName()), true);
|
||||
assertNotNull(linkedVFile1);
|
||||
|
||||
String linkedPath2 = myContentDir.getPath() + "/linked2";
|
||||
IoTestUtil.createSymLink(myCanonicalDir.getPath(), linkedPath2, true);
|
||||
VirtualFile linkedVFile2 = VfsUtil.findFileByIoFile(new File(linkedPath2, myCanonicalFile.getName()), true);
|
||||
IoTestUtil.createSymLink(myNonContentDir.getPath(), linkedPath2, true);
|
||||
VirtualFile linkedVFile2 = VfsUtil.findFileByIoFile(new File(linkedPath2, myNonContentFile.getName()), true);
|
||||
assertNotNull(linkedVFile2);
|
||||
|
||||
VirtualFile found = ProjectRootUtil.findSymlinkedFileInContent(getProject(), myCanonicalVFile);
|
||||
VirtualFile found = ProjectRootUtil.findSymlinkedFileInContent(getProject(), myNonContentVFile);
|
||||
assertTrue(found.equals(linkedVFile1) || found.equals(linkedVFile2));
|
||||
for(int i = 0; i < 10; i++) {
|
||||
assertEquals("try: " + i, found, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myCanonicalVFile));
|
||||
assertEquals("try: " + i, found, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myNonContentVFile));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,15 +134,33 @@ public class ProjectRootUtilSymlinkedFilesTest extends PlatformTestCase {
|
||||
|
||||
private void doTestLinkedAndCanonicalUnderRoot(boolean content) throws InterruptedException, IOException {
|
||||
String linkedPath = myContentDir.getPath() + "/linked";
|
||||
IoTestUtil.createSymLink(myCanonicalDir.getPath(), linkedPath, true);
|
||||
IoTestUtil.createSymLink(myNonContentDir.getPath(), linkedPath, true);
|
||||
|
||||
VirtualFile linkedVFile = VfsUtil.findFileByIoFile(new File(linkedPath, myCanonicalFile.getName()), true);
|
||||
assertEquals(linkedVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myCanonicalVFile));
|
||||
VirtualFile linkedVFile = VfsUtil.findFileByIoFile(new File(linkedPath, myNonContentFile.getName()), true);
|
||||
assertEquals(linkedVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myNonContentVFile));
|
||||
if(content) {
|
||||
PsiTestUtil.addContentRoot(getModule(), myCanonicalVFile.getParent());
|
||||
PsiTestUtil.addContentRoot(getModule(), myNonContentVFile.getParent());
|
||||
} else {
|
||||
PsiTestUtil.addLibrary(getModule(), myCanonicalVFile.getParent().getPath());
|
||||
PsiTestUtil.addLibrary(getModule(), myNonContentVFile.getParent().getPath());
|
||||
}
|
||||
assertEquals(myCanonicalVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myCanonicalVFile));
|
||||
assertEquals(myNonContentVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myNonContentVFile));
|
||||
}
|
||||
|
||||
public void testLinkedFileNotUnderTheContentRoot() throws Exception {
|
||||
File nonContentDir = FileUtil.createTempDirectory("nonContent2", null);
|
||||
String nonContentLinkedPath = nonContentDir + "/linked";
|
||||
|
||||
IoTestUtil.createSymLink(myNonContentDir.getPath(), nonContentLinkedPath, true);
|
||||
VirtualFile nonContentLinkedVFile = VfsUtil.findFileByIoFile(new File(nonContentLinkedPath, myNonContentFile.getName()), true);
|
||||
|
||||
assertEquals(nonContentLinkedVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), nonContentLinkedVFile));
|
||||
|
||||
String contentLinkedPath = myContentDir + "/linked";
|
||||
IoTestUtil.createSymLink(myNonContentDir.getPath(), contentLinkedPath, true);
|
||||
VirtualFile contentLinkedVFile = VfsUtil.findFileByIoFile(new File(contentLinkedPath, myNonContentFile.getName()), true);
|
||||
|
||||
assertEquals(contentLinkedVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), myNonContentVFile));
|
||||
assertEquals(contentLinkedVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), nonContentLinkedVFile));
|
||||
assertEquals(contentLinkedVFile, ProjectRootUtil.findSymlinkedFileInContent(getProject(), contentLinkedVFile));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,8 +46,9 @@ public class TestLoggerFactory implements Logger.Factory {
|
||||
|
||||
private TestLoggerFactory() { }
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public synchronized Logger getLoggerInstance(final String name) {
|
||||
public synchronized Logger getLoggerInstance(@NotNull final String name) {
|
||||
if (!myInitialized) {
|
||||
init();
|
||||
}
|
||||
|
||||
+39
-20
@@ -33,6 +33,7 @@ public class EditorMouseFixture {
|
||||
private int myModifiers;
|
||||
private int myButton = MouseEvent.BUTTON1;
|
||||
private int myLastId;
|
||||
private Component myLastComponent;
|
||||
|
||||
public EditorMouseFixture(EditorImpl editor) {
|
||||
myEditor = editor;
|
||||
@@ -46,9 +47,18 @@ public class EditorMouseFixture {
|
||||
return pressAt(1, getPoint(visualLine, visualColumn));
|
||||
}
|
||||
|
||||
public EditorMouseFixture pressAtLineNumbers(int visualLine) {
|
||||
assert myEditor.getSettings().isLineNumbersShown();
|
||||
return pressAt(myEditor.getGutterComponentEx(), 1, new Point(0, myEditor.visibleLineToY(visualLine)));
|
||||
}
|
||||
|
||||
private EditorMouseFixture pressAt(int clickCount, Point p) {
|
||||
JComponent component = myEditor.getContentComponent();
|
||||
component.dispatchEvent(new MouseEvent(component,
|
||||
return pressAt(component, clickCount, p);
|
||||
}
|
||||
|
||||
private EditorMouseFixture pressAt(Component component, int clickCount, Point p) {
|
||||
component.dispatchEvent(new MouseEvent(myLastComponent = component,
|
||||
myLastId = MouseEvent.MOUSE_PRESSED,
|
||||
System.currentTimeMillis(),
|
||||
getModifiers(),
|
||||
@@ -66,27 +76,27 @@ public class EditorMouseFixture {
|
||||
|
||||
private EditorMouseFixture release(int clickCount) {
|
||||
int oldLastId = myLastId;
|
||||
JComponent component = myEditor.getContentComponent();
|
||||
component.dispatchEvent(new MouseEvent(component,
|
||||
myLastId = MouseEvent.MOUSE_RELEASED,
|
||||
System.currentTimeMillis(),
|
||||
getModifiers(),
|
||||
myX,
|
||||
myY,
|
||||
clickCount,
|
||||
false,
|
||||
myButton));
|
||||
myLastComponent.dispatchEvent(new MouseEvent(myLastComponent,
|
||||
myLastId = MouseEvent.MOUSE_RELEASED,
|
||||
System.currentTimeMillis(),
|
||||
getModifiers(),
|
||||
myX,
|
||||
myY,
|
||||
clickCount,
|
||||
false,
|
||||
myButton));
|
||||
if (oldLastId == MouseEvent.MOUSE_PRESSED) {
|
||||
component.dispatchEvent(new MouseEvent(component,
|
||||
myLastId = MouseEvent.MOUSE_CLICKED,
|
||||
System.currentTimeMillis(),
|
||||
getModifiers(),
|
||||
myX,
|
||||
myY,
|
||||
clickCount,
|
||||
false,
|
||||
myButton));
|
||||
myLastComponent.dispatchEvent(new MouseEvent(myLastComponent,
|
||||
myLastId = MouseEvent.MOUSE_CLICKED,
|
||||
System.currentTimeMillis(),
|
||||
getModifiers(),
|
||||
myX,
|
||||
myY,
|
||||
clickCount,
|
||||
false,
|
||||
myButton));
|
||||
}
|
||||
myLastComponent = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -107,10 +117,19 @@ public class EditorMouseFixture {
|
||||
return dragToXY(p.x, p.y);
|
||||
}
|
||||
|
||||
public EditorMouseFixture dragToLineNumbers(int visualLine) {
|
||||
assert myEditor.getSettings().isLineNumbersShown();
|
||||
return dragToXY(myEditor.getGutterComponentEx(), 0, myEditor.visibleLineToY(visualLine));
|
||||
}
|
||||
|
||||
public EditorMouseFixture dragToXY(int x, int y) {
|
||||
Assert.assertFalse("Cannot test mouse dragging: editor visible size is not set. Use EditorTestUtil.setEditorVisibleSize(width, height)",
|
||||
myEditor.getScrollingModel().getVisibleArea().isEmpty());
|
||||
JComponent component = myEditor.getContentComponent();
|
||||
return dragToXY(component, x, y);
|
||||
}
|
||||
|
||||
private EditorMouseFixture dragToXY(JComponent component, int x, int y) {
|
||||
component.dispatchEvent(new MouseEvent(component,
|
||||
myLastId = MouseEvent.MOUSE_DRAGGED,
|
||||
System.currentTimeMillis(),
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.intellij.openapi.diagnostic;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.ExceptionUtil;
|
||||
import com.intellij.util.Function;
|
||||
import org.apache.log4j.Level;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -81,17 +80,8 @@ public class DefaultLogger extends Logger {
|
||||
//noinspection ThrowableResultOfMethodCallIgnored
|
||||
Throwable rootCause = t == null ? null : ExceptionUtil.getRootCause(t);
|
||||
if (rootCause instanceof ExceptionWithAttachments) {
|
||||
return "\nAttachments:" + StringUtil.join(((ExceptionWithAttachments)rootCause).getAttachments(),
|
||||
new Function<Attachment, String>() {
|
||||
@Override
|
||||
public String fun(Attachment attachment) {
|
||||
return attachment.getPath() + "\n" + attachment.getDisplayText();
|
||||
}
|
||||
},
|
||||
"\n----\n");
|
||||
return "\nAttachments:" + StringUtil.join(((ExceptionWithAttachments)rootCause).getAttachments(), ATTACHMENT_TO_STRING, "\n----\n");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
public class Log4jBasedLogger extends Logger {
|
||||
protected final org.apache.log4j.Logger myLogger;
|
||||
|
||||
public Log4jBasedLogger(org.apache.log4j.Logger delegate) {
|
||||
public Log4jBasedLogger(@NotNull org.apache.log4j.Logger delegate) {
|
||||
myLogger = delegate;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ package com.intellij.openapi.diagnostic;
|
||||
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ExceptionUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.apache.log4j.Level;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -27,19 +29,21 @@ import java.lang.reflect.Constructor;
|
||||
|
||||
public abstract class Logger {
|
||||
public interface Factory {
|
||||
Logger getLoggerInstance(String category);
|
||||
@NotNull
|
||||
Logger getLoggerInstance(@NotNull String category);
|
||||
}
|
||||
|
||||
private static class DefaultFactory implements Factory {
|
||||
@NotNull
|
||||
@Override
|
||||
public Logger getLoggerInstance(String category) {
|
||||
public Logger getLoggerInstance(@NotNull String category) {
|
||||
return new DefaultLogger(category);
|
||||
}
|
||||
}
|
||||
|
||||
private static Factory ourFactory = new DefaultFactory();
|
||||
|
||||
public static void setFactory(Class<? extends Factory> factory) {
|
||||
public static void setFactory(@NotNull Class<? extends Factory> factory) {
|
||||
if (isInitialized()) {
|
||||
if (factory.isInstance(ourFactory)) {
|
||||
return;
|
||||
@@ -65,12 +69,13 @@ public abstract class Logger {
|
||||
return !(ourFactory instanceof DefaultFactory);
|
||||
}
|
||||
|
||||
public static Logger getInstance(@NonNls String category) {
|
||||
@NotNull
|
||||
public static Logger getInstance(@NotNull @NonNls String category) {
|
||||
return ourFactory.getLoggerInstance(category);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Logger getInstance(Class cl) {
|
||||
public static Logger getInstance(@NotNull Class cl) {
|
||||
return getInstance("#" + cl.getName());
|
||||
}
|
||||
|
||||
@@ -82,12 +87,12 @@ public abstract class Logger {
|
||||
|
||||
public abstract void debug(@NonNls String message, @Nullable Throwable t);
|
||||
|
||||
public void debug(@NotNull String message, Object... details) {
|
||||
public void debug(@NotNull String message, @NotNull Object... details) {
|
||||
if (isDebugEnabled()) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(message);
|
||||
for (Object detail : details) {
|
||||
sb.append(String.valueOf(detail));
|
||||
sb.append(detail);
|
||||
}
|
||||
debug(sb.toString());
|
||||
}
|
||||
@@ -130,11 +135,18 @@ public abstract class Logger {
|
||||
error(String.valueOf(message));
|
||||
}
|
||||
|
||||
public void error(@NonNls String message, Attachment... attachments) {
|
||||
error(message);
|
||||
static final Function<Attachment, String> ATTACHMENT_TO_STRING = new Function<Attachment, String>() {
|
||||
@Override
|
||||
public String fun(Attachment attachment) {
|
||||
return attachment.getPath() + "\n" + attachment.getDisplayText();
|
||||
}
|
||||
};
|
||||
|
||||
public void error(@NonNls String message, @NotNull Attachment... attachments) {
|
||||
error(message, null, ContainerUtil.map2Array(attachments, String.class, ATTACHMENT_TO_STRING));
|
||||
}
|
||||
|
||||
public void error(@NonNls String message, @NonNls String... details) {
|
||||
public void error(@NonNls String message, @NonNls @NotNull String... details) {
|
||||
error(message, new Throwable(), details);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ class MissortedModifiers {
|
||||
|
||||
//@Type(type = "org.joda.time.contrib.hibernate.PersistentYearMonthDay")
|
||||
//@Column(name = "current_month")
|
||||
<warning descr="Missorted modifiers 'final public @Nullable // commment @NotNull'">final
|
||||
<warning descr="Missorted modifiers 'final public @Nullable // commment @NotNull'">final
|
||||
public
|
||||
@Nullable
|
||||
// commment
|
||||
|
||||
@@ -56,11 +56,11 @@ public class YAMLBreadcrumbsInfoProvider extends BreadcrumbsInfoProvider {
|
||||
return ((YAMLKeyValue)e).getKeyText() + ':';
|
||||
}
|
||||
if (e instanceof YAMLSequenceItem) {
|
||||
final YAMLSequence parent = (YAMLSequence)e.getParent();
|
||||
if (parent == null) {
|
||||
final PsiElement parent = e.getParent();
|
||||
if (!(parent instanceof YAMLSequence)) {
|
||||
return "Item";
|
||||
}
|
||||
final List<YAMLSequenceItem> items = parent.getItems();
|
||||
final List<YAMLSequenceItem> items = ((YAMLSequence)parent).getItems();
|
||||
return "Item " + getIndexOf(items, e);
|
||||
}
|
||||
if (e instanceof YAMLScalar) {
|
||||
|
||||
@@ -61,12 +61,18 @@ public class YAMLBreadcrumbsTest extends LightPlatformCodeInsightFixtureTestCase
|
||||
"bar: asjdjkas,\n" +
|
||||
"baz: [foo: qoo, boo: fo<caret>o, doo: 123]\n" +
|
||||
"}\n" +
|
||||
"---\n" +
|
||||
"foo: \n" +
|
||||
" bar:\n" +
|
||||
"- av<caret>r\n" +
|
||||
"...";
|
||||
private static final String OUTPUT = "[Document 1/2;null][items:;null][Item 2/2;null][descrip:;null][High Heeled \"Ruby\" S...;null]\n" +
|
||||
private static final String OUTPUT = "[Document 1/3;null][items:;null][Item 2/2;null][descrip:;null][High Heeled \"Ruby\" S...;null]\n" +
|
||||
"------\n" +
|
||||
"[Document 1/2;null][specialDelivery:;null][Follow the Yellow Br...;null]\n" +
|
||||
"[Document 1/3;null][specialDelivery:;null][Follow the Yellow Br...;null]\n" +
|
||||
"------\n" +
|
||||
"[Document 2/2;null][baz:;null][Item 2/3;null][boo:;null][foo;null]";
|
||||
"[Document 2/3;null][baz:;null][Item 2/3;null][boo:;null][foo;null]\n" +
|
||||
"------\n" +
|
||||
"[Document 3/3;null][foo:;null][Item;null][avr;null]";
|
||||
|
||||
public void testAll() {
|
||||
myFixture.configureByText(YAMLFileType.YML, INPUT);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import org.apache.tools.ant.taskdefs.condition.Os
|
||||
|
||||
plugins {
|
||||
id "com.jetbrains.python.envs" version "0.0.6"
|
||||
id "com.jetbrains.python.envs" version "0.0.7"
|
||||
}
|
||||
|
||||
|
||||
@@ -12,16 +12,16 @@ envs {
|
||||
packages = ["pip", "setuptools"]
|
||||
_64Bits = true
|
||||
|
||||
conda "django19", "2.7", ["django==1.9", "tox", "nose", "pytest", "behave", "lettuce>=0.2.22"]
|
||||
conda "django19", "2.7", ["django==1.9", "tox", "nose", "pytest", "behave", "lettuce>=0.2.22"], true
|
||||
textfile "django19/tags.txt", "django\nnose\npytest\nbehave\nlettuce\npackaging\ntox"
|
||||
|
||||
conda "django18", "2.7", ["django==1.6"]
|
||||
conda "django18", "2.7", ["django==1.6"], false
|
||||
textfile "django18/tags.txt", "django"
|
||||
|
||||
conda "django17", "2.7", ["django==1.7"]
|
||||
conda "django17", "2.7", ["django==1.7"], false
|
||||
textfile "django17/tags.txt", "django\nskeletons"
|
||||
|
||||
conda "python34", "3.4", ["ipython==2.1", "django==1.6", "behave", "jinja2", "tox>=2.0", "pandas"]
|
||||
|
||||
conda "python34", "3.4", ["ipython==2.1", "django==1.6", "behave", "jinja2", "tox>=2.0", "pandas"], true
|
||||
textfile "python34/tags.txt", "python3\nipython\nipython200\nskeletons\ndjango\nbehave\ntox\njinja2\npython34\npackaging\npandas"
|
||||
|
||||
if (!Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||
@@ -32,7 +32,7 @@ envs {
|
||||
// textfile "pyqt5/tags.txt", "pyqt5"
|
||||
}
|
||||
|
||||
conda "django_latest", "3.5", ["django"]
|
||||
conda "django_latest", "3.5", ["django"], true
|
||||
textfile "django_latest/tags.txt", "django"
|
||||
}
|
||||
|
||||
|
||||
+14
@@ -20,6 +20,7 @@ import com.intellij.execution.testframework.sm.runner.SMTestProxy;
|
||||
import com.intellij.execution.testframework.sm.runner.ui.MockPrinter;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.jetbrains.python.sdkTools.SdkCreationType;
|
||||
import com.jetbrains.python.testing.tox.PyToxConfiguration;
|
||||
import com.jetbrains.python.testing.tox.PyToxConfigurationFactory;
|
||||
@@ -30,6 +31,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
@@ -362,6 +364,18 @@ public final class PyToxTest extends PyEnvTestCase {
|
||||
private MyTestProcessRunner(final int timesToRerunFailedTests) {
|
||||
super(PyToxConfigurationFactory.INSTANCE, PyToxConfiguration.class, timesToRerunFailedTests);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configurationCreatedAndWillLaunch(@NotNull PyToxConfiguration configuration) throws IOException {
|
||||
super.configurationCreatedAndWillLaunch(configuration);
|
||||
|
||||
// To help tox with all interpreters, we add all our environments to path
|
||||
// Envs should have binaries like "python2.7" (with version included),
|
||||
// and tox will find em: see tox_get_python_executable @ interpreters.py
|
||||
final String join = StringUtil.join(getPythonRoots(), File.pathSeparator);
|
||||
configuration.getEnvs().put("PATH", join);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static final class InterpreterExpectations {
|
||||
|
||||
Reference in New Issue
Block a user