diff --git a/bin/win/IdeaWin32.dll b/bin/win/IdeaWin32.dll index c1f03bf19449..a610544ab33c 100644 Binary files a/bin/win/IdeaWin32.dll and b/bin/win/IdeaWin32.dll differ diff --git a/java/java-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java b/java/java-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java index ef229d0e292f..a569895e8f16 100644 --- a/java/java-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java +++ b/java/java-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java @@ -375,7 +375,7 @@ public class GuessManagerImpl extends GuessManager { private static class ExpressionTypeInstructionVisitor extends InstructionVisitor { private Map myResult; - private PsiElement myForPlace; + private final PsiElement myForPlace; private ExpressionTypeInstructionVisitor(PsiElement forPlace) { myForPlace = forPlace; diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java index 88d2df918594..8afa22ee089e 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java @@ -56,4 +56,6 @@ public interface DfaMemoryState { boolean checkNotNullable(DfaValue value); boolean canBeNaN(DfaValue dfaValue); + + boolean isNotNull(DfaVariableValue dfaVar); } diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java index b293440eb26d..7cdb9aaaf144 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java @@ -471,7 +471,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { return false; } - private boolean isNotNull(DfaVariableValue dfaVar) { + public boolean isNotNull(DfaVariableValue dfaVar) { DfaConstValue dfaNull = myFactory.getConstFactory().getNull(); int c1Index = getOrCreateEqClassIndex(dfaVar); int c2Index = getOrCreateEqClassIndex(dfaNull); diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java index 6c12e8dc5e8b..3faa8ad5c62c 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java @@ -32,6 +32,7 @@ import com.intellij.codeInspection.dataFlow.instructions.AssignInstruction; import com.intellij.codeInspection.dataFlow.instructions.Instruction; import com.intellij.codeInspection.dataFlow.value.DfaVariableValue; import com.intellij.codeInspection.dataFlow.value.DfaValue; +import gnu.trove.THashSet; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.NotNull; @@ -76,7 +77,29 @@ public class DfaUtil { final Collection expressions = value == null ? null : value.get(variable); return expressions == null ? Collections.emptyList() : expressions; } - + + public static enum Nullness { + NOT_NULL,NULL,UNKNOWN + } + // TRUE->not null, FALSE->null, null->unknown + @NotNull + public static Nullness checkNullness(@Nullable final PsiVariable variable, @Nullable final PsiElement context) { + if (variable == null || context == null) return Nullness.UNKNOWN; + + final PsiElement codeBlock = getEnclosingCodeBlock(variable, context); + if (codeBlock == null) { + return Nullness.UNKNOWN; + } + final ValuableInstructionVisitor visitor = new ValuableInstructionVisitor(context); + RunnerResult result = new ValuableDataFlowRunner().analyzeMethod(codeBlock, visitor); + if (result != RunnerResult.OK) { + return Nullness.UNKNOWN; + } + if (visitor.myNulls.contains(variable)) return Nullness.NULL; + if (visitor.myNotNulls.contains(variable)) return Nullness.NOT_NULL; + return Nullness.UNKNOWN; + } + @Nullable public static PsiCodeBlock getTopmostBlockInSameClass(@NotNull PsiElement position) { PsiCodeBlock block = PsiTreeUtil.getParentOfType(position, PsiCodeBlock.class, false, PsiMember.class, PsiFile.class); @@ -198,6 +221,8 @@ public class DfaUtil { private static class ValuableInstructionVisitor extends StandardInstructionVisitor { final MultiValuesMap myValues = new MultiValuesMap(true); + final Set myNulls = new THashSet(); + final Set myNotNulls = new THashSet(); private final PsiElement myContext; public ValuableInstructionVisitor(PsiElement context) { @@ -216,6 +241,15 @@ public class DfaUtil { myValues.put(variableValue.getPsiVariable(), psiExpression); } } + DfaValue value = instruction.getValue(); + if (value instanceof DfaVariableValue) { + if (memState.isNotNull((DfaVariableValue)value)) { + myNotNulls.add(((DfaVariableValue)value).getPsiVariable()); + } + if (memState.isNull(value)) { + myNulls.add(((DfaVariableValue)value).getPsiVariable()); + } + } } return super.visitPush(instruction, runner, memState); } diff --git a/java/java-impl/src/com/intellij/codeInspection/unusedLibraries/UnusedLibrariesInspection.java b/java/java-impl/src/com/intellij/codeInspection/unusedLibraries/UnusedLibrariesInspection.java index 0c87b4ce8013..00f0f49ea195 100644 --- a/java/java-impl/src/com/intellij/codeInspection/unusedLibraries/UnusedLibrariesInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/unusedLibraries/UnusedLibrariesInspection.java @@ -87,13 +87,15 @@ public class UnusedLibrariesInspection extends DescriptorProviderInspection { }); libraryRoots.addAll(Arrays.asList(LibraryUtil.getLibraryRoots(modules.toArray(new Module[modules.size()]), false, false))); } - GlobalSearchScope searchScope = null; + GlobalSearchScope searchScope; try { @NonNls final String libsName = "libs"; searchScope = GlobalSearchScope.filterScope(project, new NamedScope(libsName, PackageSetFactory.getInstance().compile("lib:*..*"))); } catch (ParsingException e) { //can't be + LOG.error(e); + return; } final AnalysisScope analysisScope = new AnalysisScope(searchScope, project); analysisScope.setSearchInLibraries(true); diff --git a/java/java-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java b/java/java-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java index 2dd05ffd03e8..3a1c401507ee 100644 --- a/java/java-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java @@ -536,7 +536,7 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx implements Disposable { } private void checkModifierListOwner(PsiElement child) { - if (child instanceof PsiModifierListOwner) { + if (child instanceof PsiClass || child instanceof PsiMethod) { PsiModifierList modifierList = ((PsiModifierListOwner)child).getModifierList(); if (modifierList != null && modifierList.getAnnotations().length > 0) { myModificationTracker.incAnnotationModificationCounter(); diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesHandler.java index 67bac1d6d09e..f8520402ae25 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesHandler.java @@ -29,7 +29,11 @@ public class MoveClassesHandler extends MoveClassesOrPackagesHandlerBase { for(PsiElement element: elements) { PsiFile parentFile; if (element instanceof PsiJavaFile) { - if (((PsiJavaFile)element).getClasses().length == 0) return false; + final PsiClass[] classes = ((PsiJavaFile)element).getClasses(); + if (classes.length == 0) return false; + for (PsiClass aClass : classes) { + if (aClass instanceof JspClass) return false; + } parentFile = (PsiFile)element; } else { if (element instanceof JspClass) return false; diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodProcessor.java index aa9cb6ee38dc..6cd4d13f1111 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodProcessor.java @@ -388,12 +388,20 @@ public class MoveInstanceMethodProcessor extends BaseRefactoringProcessor{ @Override public void visitReferenceExpression(PsiReferenceExpression expression) { try { final PsiExpression qualifier = expression.getQualifierExpression(); + final PsiElement resolved = expression.resolve(); if (qualifier instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifier).isReferenceTo(myTargetVariable)) { + if (resolved instanceof PsiField) { + for (PsiParameter parameter : myMethod.getParameterList().getParameters()) { + if (Comparing.strEqual(parameter.getName(), ((PsiField)resolved).getName())) { + qualifier.replace(factory.createExpressionFromText("this", null)); + return; + } + } + } //Target is a field, replace target.m -> m qualifier.delete(); return; } - final PsiElement resolved = expression.resolve(); if (myTargetVariable.equals(resolved)) { PsiThisExpression thisExpression = (PsiThisExpression)factory.createExpressionFromText("this", null); expression.replace(thisExpression); diff --git a/java/java-tests/testData/refactoring/moveInstanceMethod/QualifyFieldAccess.java b/java/java-tests/testData/refactoring/moveInstanceMethod/QualifyFieldAccess.java new file mode 100644 index 000000000000..bb32bcf6674c --- /dev/null +++ b/java/java-tests/testData/refactoring/moveInstanceMethod/QualifyFieldAccess.java @@ -0,0 +1,12 @@ +public class Test { + + private Bar bar = new Bar(); + + public void foo(int x) { + bar.x = x; + } + + private static class Bar { + private int x; + } +} diff --git a/java/java-tests/testData/refactoring/moveInstanceMethod/QualifyFieldAccess.java.after b/java/java-tests/testData/refactoring/moveInstanceMethod/QualifyFieldAccess.java.after new file mode 100644 index 000000000000..e3fdd3af71bf --- /dev/null +++ b/java/java-tests/testData/refactoring/moveInstanceMethod/QualifyFieldAccess.java.after @@ -0,0 +1,12 @@ +public class Test { + + private Bar bar = new Bar(); + + private static class Bar { + private int x; + + public void foo(int x) { + this.x = x; + } + } +} diff --git a/java/java-tests/testData/refactoring/moveInstanceMethod/StripFieldQualifier.java b/java/java-tests/testData/refactoring/moveInstanceMethod/StripFieldQualifier.java new file mode 100644 index 000000000000..93769aaaedf6 --- /dev/null +++ b/java/java-tests/testData/refactoring/moveInstanceMethod/StripFieldQualifier.java @@ -0,0 +1,12 @@ +public class Test { + + private Bar bar = new Bar(); + + public void foo(int y) { + bar.x = y; + } + + private static class Bar { + private int x; + } +} diff --git a/java/java-tests/testData/refactoring/moveInstanceMethod/StripFieldQualifier.java.after b/java/java-tests/testData/refactoring/moveInstanceMethod/StripFieldQualifier.java.after new file mode 100644 index 000000000000..8a1abf0be79d --- /dev/null +++ b/java/java-tests/testData/refactoring/moveInstanceMethod/StripFieldQualifier.java.after @@ -0,0 +1,12 @@ +public class Test { + + private Bar bar = new Bar(); + + private static class Bar { + private int x; + + public void foo(int y) { + x = y; + } + } +} diff --git a/java/java-tests/testSrc/com/intellij/refactoring/moveMethod/MoveInstanceMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/moveMethod/MoveInstanceMethodTest.java index 83fbac9585fd..9e4f185d64e3 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/moveMethod/MoveInstanceMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/moveMethod/MoveInstanceMethodTest.java @@ -57,6 +57,14 @@ public class MoveInstanceMethodTest extends LightCodeInsightTestCase { doTest(true, 0); } + public void testQualifyFieldAccess() throws Exception { + doTest(false, 0); + } + + public void testStripFieldQualifier() throws Exception { + doTest(false, 0); + } + private void doTest(boolean isTargetParameter, final int targetIndex) throws Exception { doTest(isTargetParameter, targetIndex, null); } diff --git a/java/openapi/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java b/java/openapi/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java index 8f111a48586c..6a49e3820679 100644 --- a/java/openapi/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java +++ b/java/openapi/src/com/intellij/psi/search/searches/ClassInheritorsSearch.java @@ -162,7 +162,7 @@ public class ClassInheritorsSearch extends ExtensibleQueryFactory() { public boolean process(PsiClass aClass) { - ProgressManager.getInstance().checkCanceled(); + ProgressManager.checkCanceled(); return consumer.process(aClass); } }); @@ -173,7 +173,7 @@ public class ClassInheritorsSearch extends ExtensibleQueryFactory processed = new HashSet(); final Processor processor = new Processor() { public boolean process(final PsiClass candidate) { - ProgressManager.getInstance().checkCanceled(); + ProgressManager.checkCanceled(); final Ref result = new Ref(); ApplicationManager.getApplication().runReadAction(new Runnable() { diff --git a/native/IdeaWin32/IdeaWin32.cpp b/native/IdeaWin32/IdeaWin32.cpp new file mode 100644 index 000000000000..18cb2870dad7 --- /dev/null +++ b/native/IdeaWin32/IdeaWin32.cpp @@ -0,0 +1,128 @@ +#include "stdafx.h" +#include "IdeaWin32.h" +#include "jni_util.h" +#include "windows.h" + +jfieldID nameId; + +HANDLE FindFileInner(JNIEnv *env, jstring path, LPWIN32_FIND_DATA lpData) { + const jchar* str = env->GetStringChars(path, 0); + HANDLE h = FindFirstFile((LPCWSTR)str, lpData); + env->ReleaseStringChars(path, str); + return h; +} + +bool CopyObjectArray(JNIEnv *env, jobjectArray dst, jobjectArray src, + jint count) +{ + int i; + for (i=0; iGetObjectArrayElement(src, i); + env->SetObjectArrayElement(dst, i, p); + env->DeleteLocalRef(p); + } + return true; +} + +static LONGLONG +fileTimeToInt64 (const FILETIME * time) +{ + ULARGE_INTEGER _time; + + _time.LowPart = time->dwLowDateTime; + _time.HighPart = time->dwHighDateTime; + + return _time.QuadPart; +} + +jfieldID nameID; +jfieldID attributesID; +jfieldID timestampID; + +jobject CreateFileInfo(JNIEnv *env, LPWIN32_FIND_DATA lpData, jclass cls) { + + jobject o = env->AllocObject(cls); + if (o == NULL) { + return NULL; + } + jstring fileName = env->NewString((jchar*)lpData->cFileName, (jsize)wcslen(lpData->cFileName)); + if (fileName == NULL) { + return NULL; + } + env->SetObjectField(o, nameID, fileName); + env->SetIntField(o, attributesID, lpData->dwFileAttributes); + env->SetLongField(o, timestampID, fileTimeToInt64(&lpData->ftLastWriteTime)); + return o; +} + +JNIEXPORT void JNICALL Java_com_intellij_openapi_vfs_impl_win32_FileInfo_initIDs(JNIEnv *env, jclass cls) { + nameID = env->GetFieldID(cls, "name", "Ljava/lang/String;"); + attributesID = env->GetFieldID(cls, "attributes", "I"); + timestampID = env->GetFieldID(cls, "timestamp", "J"); +} + +JNIEXPORT jobject JNICALL Java_com_intellij_openapi_vfs_impl_win32_IdeaWin32_getInfo(JNIEnv *env, jobject method, jstring path) { + WIN32_FIND_DATA data; + HANDLE h = FindFileInner(env, path, &data); + if (h == INVALID_HANDLE_VALUE) { + return NULL; + } + FindClose(h); + jclass infoClass = env->FindClass("com/intellij/openapi/vfs/impl/win32/FileInfo"); + return CreateFileInfo(env, &data, infoClass); +} + +JNIEXPORT jobjectArray JNICALL Java_com_intellij_openapi_vfs_impl_win32_IdeaWin32_listChildren(JNIEnv *env, jobject method, jstring path) +{ + + WIN32_FIND_DATA data; + HANDLE h = FindFileInner(env, path, &data); + if (h == INVALID_HANDLE_VALUE) { + return NULL; + } + + jobjectArray rv, old; + int len, maxlen; + + len = 0; + maxlen = 16; + jclass infoClass = env->FindClass("com/intellij/openapi/vfs/impl/win32/FileInfo"); + rv = env->NewObjectArray(maxlen, infoClass, NULL); + if (rv == NULL) goto error; + do { + if (len == maxlen) { + old = rv; + rv = env->NewObjectArray(maxlen <<= 1, + infoClass, NULL); + if (rv == NULL) goto error; + if (!CopyObjectArray(env, rv, old, len)) goto error; + env->DeleteLocalRef(old); + } + jobject o = CreateFileInfo(env, &data, infoClass); + env->SetObjectArrayElement(rv, len++, o); + env->DeleteLocalRef(o); + } + while (FindNextFile(h, &data)); + + FindClose(h); + + old = rv; + rv = env->NewObjectArray(len, infoClass, NULL); + if (rv == NULL) goto error; + if (!CopyObjectArray(env, rv, old, len)) goto error; + return rv; + + +error: + FindClose(h); + return NULL; +} + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + return TRUE; +} + diff --git a/native/IdeaWin32/IdeaWin32.h b/native/IdeaWin32/IdeaWin32.h new file mode 100644 index 000000000000..2fe5bd16e17d --- /dev/null +++ b/native/IdeaWin32/IdeaWin32.h @@ -0,0 +1,15 @@ +#include "jni.h" + +#ifdef __cplusplus +extern "C" { +#endif + +JNIEXPORT void JNICALL Java_com_intellij_openapi_vfs_impl_win32_FileInfo_initIDs(JNIEnv *env, jclass cls); + +JNIEXPORT jobject JNICALL Java_com_intellij_openapi_vfs_impl_win32_IdeaWin32_getInfo(JNIEnv *env, jobject method, jstring path); + +JNIEXPORT jobjectArray JNICALL Java_com_intellij_openapi_vfs_impl_win32_IdeaWin32_listChildren(JNIEnv *env, jobject method, jstring path); + +#ifdef __cplusplus +} +#endif diff --git a/native/IdeaWin32/IdeaWin32.vcproj b/native/IdeaWin32/IdeaWin32.vcproj new file mode 100644 index 000000000000..5a8310e4d77d --- /dev/null +++ b/native/IdeaWin32/IdeaWin32.vcproj @@ -0,0 +1,230 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/native/IdeaWin32/jlong.h b/native/IdeaWin32/jlong.h new file mode 100644 index 000000000000..d3fe33fd58c7 --- /dev/null +++ b/native/IdeaWin32/jlong.h @@ -0,0 +1,31 @@ +/* + * Copyright 1997 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +#ifndef _JLONG_H_ +#define _JLONG_H_ + +#include "jlong_md.h" + +#endif diff --git a/native/IdeaWin32/jlong_md.h b/native/IdeaWin32/jlong_md.h new file mode 100644 index 000000000000..8b62f26c37e1 --- /dev/null +++ b/native/IdeaWin32/jlong_md.h @@ -0,0 +1,93 @@ +/* + * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +#ifndef _WIN32_JLONG_MD_H_ +#define _WIN32_JLONG_MD_H_ + +/* Make sure ptrdiff_t is defined */ +#include + +#define jlong_high(a) ((jint)((a)>>32)) +#define jlong_low(a) ((jint)(a)) +#define jlong_add(a, b) ((a) + (b)) +#define jlong_and(a, b) ((a) & (b)) +#define jlong_div(a, b) ((a) / (b)) +#define jlong_mul(a, b) ((a) * (b)) +#define jlong_neg(a) (-(a)) +#define jlong_not(a) (~(a)) +#define jlong_or(a, b) ((a) | (b)) +#define jlong_shl(a, n) ((a) << (n)) +#define jlong_shr(a, n) ((a) >> (n)) +#define jlong_sub(a, b) ((a) - (b)) +#define jlong_xor(a, b) ((a) ^ (b)) +#define jlong_rem(a,b) ((a) % (b)) + +/* comparison operators */ +#define jlong_ltz(ll) ((ll) < 0) +#define jlong_gez(ll) ((ll) >= 0) +#define jlong_gtz(ll) ((ll) > 0) +#define jlong_eqz(a) ((a) == 0) +#define jlong_eq(a, b) ((a) == (b)) +#define jlong_ne(a,b) ((a) != (b)) +#define jlong_ge(a,b) ((a) >= (b)) +#define jlong_le(a,b) ((a) <= (b)) +#define jlong_lt(a,b) ((a) < (b)) +#define jlong_gt(a,b) ((a) > (b)) + +#define jlong_zero ((jlong) 0) +#define jlong_one ((jlong) 1) +#define jlong_minus_one ((jlong) -1) + +/* For static variables initialized to zero */ +#define jlong_zero_init ((jlong) 0) + +#ifdef _WIN64 +#define jlong_to_ptr(a) ((void*)(a)) +#define ptr_to_jlong(a) ((jlong)(a)) +#else +/* Double casting to avoid warning messages looking for casting of */ +/* smaller sizes into pointers */ +#define jlong_to_ptr(a) ((void*)(int)(a)) +#define ptr_to_jlong(a) ((jlong)(int)(a)) +#endif + +#define jint_to_jlong(a) ((jlong)(a)) +#define jlong_to_jint(a) ((jint)(a)) + +/* Useful on machines where jlong and jdouble have different endianness. */ +#define jlong_to_jdouble_bits(a) +#define jdouble_to_jlong_bits(a) + +#define jlong_to_int(a) ((int)(a)) +#define int_to_jlong(a) ((jlong)(a)) +#define jlong_to_uint(a) ((unsigned int)(a)) +#define uint_to_jlong(a) ((jlong)(a)) +#define jlong_to_ptrdiff(a) ((ptrdiff_t)(a)) +#define ptrdiff_to_jlong(a) ((jlong)(a)) +#define jlong_to_size(a) ((size_t)(a)) +#define size_to_jlong(a) ((jlong)(a)) +#define long_to_jlong(a) ((jlong)(a)) + +#endif diff --git a/native/IdeaWin32/jni.h b/native/IdeaWin32/jni.h new file mode 100644 index 000000000000..f53476c09671 --- /dev/null +++ b/native/IdeaWin32/jni.h @@ -0,0 +1,1944 @@ +/* + * @(#)jni.h 1.62 06/02/02 + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +/* + * We used part of Netscape's Java Runtime Interface (JRI) as the starting + * point of our design and implementation. + */ + +/****************************************************************************** + * Java Runtime Interface + * Copyright (c) 1996 Netscape Communications Corporation. All rights reserved. + *****************************************************************************/ + +#ifndef _JAVASOFT_JNI_H_ +#define _JAVASOFT_JNI_H_ + +#include +#include + +/* jni_md.h contains the machine-dependent typedefs for jbyte, jint + and jlong */ + +#include "jni_md.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * JNI Types + */ + +#ifndef JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H + +typedef unsigned char jboolean; +typedef unsigned short jchar; +typedef short jshort; +typedef float jfloat; +typedef double jdouble; + +typedef jint jsize; + +#ifdef __cplusplus + +class _jobject {}; +class _jclass : public _jobject {}; +class _jthrowable : public _jobject {}; +class _jstring : public _jobject {}; +class _jarray : public _jobject {}; +class _jbooleanArray : public _jarray {}; +class _jbyteArray : public _jarray {}; +class _jcharArray : public _jarray {}; +class _jshortArray : public _jarray {}; +class _jintArray : public _jarray {}; +class _jlongArray : public _jarray {}; +class _jfloatArray : public _jarray {}; +class _jdoubleArray : public _jarray {}; +class _jobjectArray : public _jarray {}; + +typedef _jobject *jobject; +typedef _jclass *jclass; +typedef _jthrowable *jthrowable; +typedef _jstring *jstring; +typedef _jarray *jarray; +typedef _jbooleanArray *jbooleanArray; +typedef _jbyteArray *jbyteArray; +typedef _jcharArray *jcharArray; +typedef _jshortArray *jshortArray; +typedef _jintArray *jintArray; +typedef _jlongArray *jlongArray; +typedef _jfloatArray *jfloatArray; +typedef _jdoubleArray *jdoubleArray; +typedef _jobjectArray *jobjectArray; + +#else + +struct _jobject; + +typedef struct _jobject *jobject; +typedef jobject jclass; +typedef jobject jthrowable; +typedef jobject jstring; +typedef jobject jarray; +typedef jarray jbooleanArray; +typedef jarray jbyteArray; +typedef jarray jcharArray; +typedef jarray jshortArray; +typedef jarray jintArray; +typedef jarray jlongArray; +typedef jarray jfloatArray; +typedef jarray jdoubleArray; +typedef jarray jobjectArray; + +#endif + +typedef jobject jweak; + +typedef union jvalue { + jboolean z; + jbyte b; + jchar c; + jshort s; + jint i; + jlong j; + jfloat f; + jdouble d; + jobject l; +} jvalue; + +struct _jfieldID; +typedef struct _jfieldID *jfieldID; + +struct _jmethodID; +typedef struct _jmethodID *jmethodID; + +/* Return values from jobjectRefType */ +typedef enum _jobjectType { + JNIInvalidRefType = 0, + JNILocalRefType = 1, + JNIGlobalRefType = 2, + JNIWeakGlobalRefType = 3 +} jobjectRefType; + + +#endif /* JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H */ + +/* + * jboolean constants + */ + +#define JNI_FALSE 0 +#define JNI_TRUE 1 + +/* + * possible return values for JNI functions. + */ + +#define JNI_OK 0 /* success */ +#define JNI_ERR (-1) /* unknown error */ +#define JNI_EDETACHED (-2) /* thread detached from the VM */ +#define JNI_EVERSION (-3) /* JNI version error */ +#define JNI_ENOMEM (-4) /* not enough memory */ +#define JNI_EEXIST (-5) /* VM already created */ +#define JNI_EINVAL (-6) /* invalid arguments */ + +/* + * used in ReleaseScalarArrayElements + */ + +#define JNI_COMMIT 1 +#define JNI_ABORT 2 + +/* + * used in RegisterNatives to describe native method name, signature, + * and function pointer. + */ + +typedef struct { + char *name; + char *signature; + void *fnPtr; +} JNINativeMethod; + +/* + * JNI Native Method Interface. + */ + +struct JNINativeInterface_; + +struct JNIEnv_; + +#ifdef __cplusplus +typedef JNIEnv_ JNIEnv; +#else +typedef const struct JNINativeInterface_ *JNIEnv; +#endif + +/* + * JNI Invocation Interface. + */ + +struct JNIInvokeInterface_; + +struct JavaVM_; + +#ifdef __cplusplus +typedef JavaVM_ JavaVM; +#else +typedef const struct JNIInvokeInterface_ *JavaVM; +#endif + +struct JNINativeInterface_ { + void *reserved0; + void *reserved1; + void *reserved2; + + void *reserved3; + jint (JNICALL *GetVersion)(JNIEnv *env); + + jclass (JNICALL *DefineClass) + (JNIEnv *env, const char *name, jobject loader, const jbyte *buf, + jsize len); + jclass (JNICALL *FindClass) + (JNIEnv *env, const char *name); + + jmethodID (JNICALL *FromReflectedMethod) + (JNIEnv *env, jobject method); + jfieldID (JNICALL *FromReflectedField) + (JNIEnv *env, jobject field); + + jobject (JNICALL *ToReflectedMethod) + (JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic); + + jclass (JNICALL *GetSuperclass) + (JNIEnv *env, jclass sub); + jboolean (JNICALL *IsAssignableFrom) + (JNIEnv *env, jclass sub, jclass sup); + + jobject (JNICALL *ToReflectedField) + (JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic); + + jint (JNICALL *Throw) + (JNIEnv *env, jthrowable obj); + jint (JNICALL *ThrowNew) + (JNIEnv *env, jclass clazz, const char *msg); + jthrowable (JNICALL *ExceptionOccurred) + (JNIEnv *env); + void (JNICALL *ExceptionDescribe) + (JNIEnv *env); + void (JNICALL *ExceptionClear) + (JNIEnv *env); + void (JNICALL *FatalError) + (JNIEnv *env, const char *msg); + + jint (JNICALL *PushLocalFrame) + (JNIEnv *env, jint capacity); + jobject (JNICALL *PopLocalFrame) + (JNIEnv *env, jobject result); + + jobject (JNICALL *NewGlobalRef) + (JNIEnv *env, jobject lobj); + void (JNICALL *DeleteGlobalRef) + (JNIEnv *env, jobject gref); + void (JNICALL *DeleteLocalRef) + (JNIEnv *env, jobject obj); + jboolean (JNICALL *IsSameObject) + (JNIEnv *env, jobject obj1, jobject obj2); + jobject (JNICALL *NewLocalRef) + (JNIEnv *env, jobject ref); + jint (JNICALL *EnsureLocalCapacity) + (JNIEnv *env, jint capacity); + + jobject (JNICALL *AllocObject) + (JNIEnv *env, jclass clazz); + jobject (JNICALL *NewObject) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *NewObjectV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jobject (JNICALL *NewObjectA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jclass (JNICALL *GetObjectClass) + (JNIEnv *env, jobject obj); + jboolean (JNICALL *IsInstanceOf) + (JNIEnv *env, jobject obj, jclass clazz); + + jmethodID (JNICALL *GetMethodID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *CallObjectMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jobject (JNICALL *CallObjectMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jobject (JNICALL *CallObjectMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jboolean (JNICALL *CallBooleanMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jboolean (JNICALL *CallBooleanMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jboolean (JNICALL *CallBooleanMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jbyte (JNICALL *CallByteMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jbyte (JNICALL *CallByteMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jbyte (JNICALL *CallByteMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jchar (JNICALL *CallCharMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jchar (JNICALL *CallCharMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jchar (JNICALL *CallCharMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jshort (JNICALL *CallShortMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jshort (JNICALL *CallShortMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jshort (JNICALL *CallShortMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jint (JNICALL *CallIntMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jint (JNICALL *CallIntMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jint (JNICALL *CallIntMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jlong (JNICALL *CallLongMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jlong (JNICALL *CallLongMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jlong (JNICALL *CallLongMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jfloat (JNICALL *CallFloatMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jfloat (JNICALL *CallFloatMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jfloat (JNICALL *CallFloatMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jdouble (JNICALL *CallDoubleMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jdouble (JNICALL *CallDoubleMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jdouble (JNICALL *CallDoubleMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + void (JNICALL *CallVoidMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + void (JNICALL *CallVoidMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + void (JNICALL *CallVoidMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jobject (JNICALL *CallNonvirtualObjectMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *CallNonvirtualObjectMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jobject (JNICALL *CallNonvirtualObjectMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jboolean (JNICALL *CallNonvirtualBooleanMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jboolean (JNICALL *CallNonvirtualBooleanMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jboolean (JNICALL *CallNonvirtualBooleanMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jbyte (JNICALL *CallNonvirtualByteMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jbyte (JNICALL *CallNonvirtualByteMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jbyte (JNICALL *CallNonvirtualByteMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jchar (JNICALL *CallNonvirtualCharMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jchar (JNICALL *CallNonvirtualCharMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jchar (JNICALL *CallNonvirtualCharMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jshort (JNICALL *CallNonvirtualShortMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jshort (JNICALL *CallNonvirtualShortMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jshort (JNICALL *CallNonvirtualShortMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jint (JNICALL *CallNonvirtualIntMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jint (JNICALL *CallNonvirtualIntMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jint (JNICALL *CallNonvirtualIntMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jlong (JNICALL *CallNonvirtualLongMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jlong (JNICALL *CallNonvirtualLongMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jlong (JNICALL *CallNonvirtualLongMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jfloat (JNICALL *CallNonvirtualFloatMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jfloat (JNICALL *CallNonvirtualFloatMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jfloat (JNICALL *CallNonvirtualFloatMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jdouble (JNICALL *CallNonvirtualDoubleMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jdouble (JNICALL *CallNonvirtualDoubleMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jdouble (JNICALL *CallNonvirtualDoubleMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + void (JNICALL *CallNonvirtualVoidMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + void (JNICALL *CallNonvirtualVoidMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + void (JNICALL *CallNonvirtualVoidMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jfieldID (JNICALL *GetFieldID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *GetObjectField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jboolean (JNICALL *GetBooleanField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jbyte (JNICALL *GetByteField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jchar (JNICALL *GetCharField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jshort (JNICALL *GetShortField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jint (JNICALL *GetIntField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jlong (JNICALL *GetLongField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jfloat (JNICALL *GetFloatField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jdouble (JNICALL *GetDoubleField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + + void (JNICALL *SetObjectField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val); + void (JNICALL *SetBooleanField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val); + void (JNICALL *SetByteField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val); + void (JNICALL *SetCharField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val); + void (JNICALL *SetShortField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val); + void (JNICALL *SetIntField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jint val); + void (JNICALL *SetLongField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val); + void (JNICALL *SetFloatField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val); + void (JNICALL *SetDoubleField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val); + + jmethodID (JNICALL *GetStaticMethodID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *CallStaticObjectMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *CallStaticObjectMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jobject (JNICALL *CallStaticObjectMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jboolean (JNICALL *CallStaticBooleanMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jboolean (JNICALL *CallStaticBooleanMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jboolean (JNICALL *CallStaticBooleanMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jbyte (JNICALL *CallStaticByteMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jbyte (JNICALL *CallStaticByteMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jbyte (JNICALL *CallStaticByteMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jchar (JNICALL *CallStaticCharMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jchar (JNICALL *CallStaticCharMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jchar (JNICALL *CallStaticCharMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jshort (JNICALL *CallStaticShortMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jshort (JNICALL *CallStaticShortMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jshort (JNICALL *CallStaticShortMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jint (JNICALL *CallStaticIntMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jint (JNICALL *CallStaticIntMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jint (JNICALL *CallStaticIntMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jlong (JNICALL *CallStaticLongMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jlong (JNICALL *CallStaticLongMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jlong (JNICALL *CallStaticLongMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jfloat (JNICALL *CallStaticFloatMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jfloat (JNICALL *CallStaticFloatMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jfloat (JNICALL *CallStaticFloatMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jdouble (JNICALL *CallStaticDoubleMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jdouble (JNICALL *CallStaticDoubleMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jdouble (JNICALL *CallStaticDoubleMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + void (JNICALL *CallStaticVoidMethod) + (JNIEnv *env, jclass cls, jmethodID methodID, ...); + void (JNICALL *CallStaticVoidMethodV) + (JNIEnv *env, jclass cls, jmethodID methodID, va_list args); + void (JNICALL *CallStaticVoidMethodA) + (JNIEnv *env, jclass cls, jmethodID methodID, const jvalue * args); + + jfieldID (JNICALL *GetStaticFieldID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + jobject (JNICALL *GetStaticObjectField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jboolean (JNICALL *GetStaticBooleanField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jbyte (JNICALL *GetStaticByteField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jchar (JNICALL *GetStaticCharField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jshort (JNICALL *GetStaticShortField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jint (JNICALL *GetStaticIntField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jlong (JNICALL *GetStaticLongField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jfloat (JNICALL *GetStaticFloatField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jdouble (JNICALL *GetStaticDoubleField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + + void (JNICALL *SetStaticObjectField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value); + void (JNICALL *SetStaticBooleanField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value); + void (JNICALL *SetStaticByteField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value); + void (JNICALL *SetStaticCharField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value); + void (JNICALL *SetStaticShortField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value); + void (JNICALL *SetStaticIntField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value); + void (JNICALL *SetStaticLongField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value); + void (JNICALL *SetStaticFloatField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value); + void (JNICALL *SetStaticDoubleField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value); + + jstring (JNICALL *NewString) + (JNIEnv *env, const jchar *unicode, jsize len); + jsize (JNICALL *GetStringLength) + (JNIEnv *env, jstring str); + const jchar *(JNICALL *GetStringChars) + (JNIEnv *env, jstring str, jboolean *isCopy); + void (JNICALL *ReleaseStringChars) + (JNIEnv *env, jstring str, const jchar *chars); + + jstring (JNICALL *NewStringUTF) + (JNIEnv *env, const char *utf); + jsize (JNICALL *GetStringUTFLength) + (JNIEnv *env, jstring str); + const char* (JNICALL *GetStringUTFChars) + (JNIEnv *env, jstring str, jboolean *isCopy); + void (JNICALL *ReleaseStringUTFChars) + (JNIEnv *env, jstring str, const char* chars); + + + jsize (JNICALL *GetArrayLength) + (JNIEnv *env, jarray array); + + jobjectArray (JNICALL *NewObjectArray) + (JNIEnv *env, jsize len, jclass clazz, jobject init); + jobject (JNICALL *GetObjectArrayElement) + (JNIEnv *env, jobjectArray array, jsize index); + void (JNICALL *SetObjectArrayElement) + (JNIEnv *env, jobjectArray array, jsize index, jobject val); + + jbooleanArray (JNICALL *NewBooleanArray) + (JNIEnv *env, jsize len); + jbyteArray (JNICALL *NewByteArray) + (JNIEnv *env, jsize len); + jcharArray (JNICALL *NewCharArray) + (JNIEnv *env, jsize len); + jshortArray (JNICALL *NewShortArray) + (JNIEnv *env, jsize len); + jintArray (JNICALL *NewIntArray) + (JNIEnv *env, jsize len); + jlongArray (JNICALL *NewLongArray) + (JNIEnv *env, jsize len); + jfloatArray (JNICALL *NewFloatArray) + (JNIEnv *env, jsize len); + jdoubleArray (JNICALL *NewDoubleArray) + (JNIEnv *env, jsize len); + + jboolean * (JNICALL *GetBooleanArrayElements) + (JNIEnv *env, jbooleanArray array, jboolean *isCopy); + jbyte * (JNICALL *GetByteArrayElements) + (JNIEnv *env, jbyteArray array, jboolean *isCopy); + jchar * (JNICALL *GetCharArrayElements) + (JNIEnv *env, jcharArray array, jboolean *isCopy); + jshort * (JNICALL *GetShortArrayElements) + (JNIEnv *env, jshortArray array, jboolean *isCopy); + jint * (JNICALL *GetIntArrayElements) + (JNIEnv *env, jintArray array, jboolean *isCopy); + jlong * (JNICALL *GetLongArrayElements) + (JNIEnv *env, jlongArray array, jboolean *isCopy); + jfloat * (JNICALL *GetFloatArrayElements) + (JNIEnv *env, jfloatArray array, jboolean *isCopy); + jdouble * (JNICALL *GetDoubleArrayElements) + (JNIEnv *env, jdoubleArray array, jboolean *isCopy); + + void (JNICALL *ReleaseBooleanArrayElements) + (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode); + void (JNICALL *ReleaseByteArrayElements) + (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode); + void (JNICALL *ReleaseCharArrayElements) + (JNIEnv *env, jcharArray array, jchar *elems, jint mode); + void (JNICALL *ReleaseShortArrayElements) + (JNIEnv *env, jshortArray array, jshort *elems, jint mode); + void (JNICALL *ReleaseIntArrayElements) + (JNIEnv *env, jintArray array, jint *elems, jint mode); + void (JNICALL *ReleaseLongArrayElements) + (JNIEnv *env, jlongArray array, jlong *elems, jint mode); + void (JNICALL *ReleaseFloatArrayElements) + (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode); + void (JNICALL *ReleaseDoubleArrayElements) + (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode); + + void (JNICALL *GetBooleanArrayRegion) + (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf); + void (JNICALL *GetByteArrayRegion) + (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf); + void (JNICALL *GetCharArrayRegion) + (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf); + void (JNICALL *GetShortArrayRegion) + (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf); + void (JNICALL *GetIntArrayRegion) + (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf); + void (JNICALL *GetLongArrayRegion) + (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf); + void (JNICALL *GetFloatArrayRegion) + (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf); + void (JNICALL *GetDoubleArrayRegion) + (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf); + + void (JNICALL *SetBooleanArrayRegion) + (JNIEnv *env, jbooleanArray array, jsize start, jsize l, const jboolean *buf); + void (JNICALL *SetByteArrayRegion) + (JNIEnv *env, jbyteArray array, jsize start, jsize len, const jbyte *buf); + void (JNICALL *SetCharArrayRegion) + (JNIEnv *env, jcharArray array, jsize start, jsize len, const jchar *buf); + void (JNICALL *SetShortArrayRegion) + (JNIEnv *env, jshortArray array, jsize start, jsize len, const jshort *buf); + void (JNICALL *SetIntArrayRegion) + (JNIEnv *env, jintArray array, jsize start, jsize len, const jint *buf); + void (JNICALL *SetLongArrayRegion) + (JNIEnv *env, jlongArray array, jsize start, jsize len, const jlong *buf); + void (JNICALL *SetFloatArrayRegion) + (JNIEnv *env, jfloatArray array, jsize start, jsize len, const jfloat *buf); + void (JNICALL *SetDoubleArrayRegion) + (JNIEnv *env, jdoubleArray array, jsize start, jsize len, const jdouble *buf); + + jint (JNICALL *RegisterNatives) + (JNIEnv *env, jclass clazz, const JNINativeMethod *methods, + jint nMethods); + jint (JNICALL *UnregisterNatives) + (JNIEnv *env, jclass clazz); + + jint (JNICALL *MonitorEnter) + (JNIEnv *env, jobject obj); + jint (JNICALL *MonitorExit) + (JNIEnv *env, jobject obj); + + jint (JNICALL *GetJavaVM) + (JNIEnv *env, JavaVM **vm); + + void (JNICALL *GetStringRegion) + (JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf); + void (JNICALL *GetStringUTFRegion) + (JNIEnv *env, jstring str, jsize start, jsize len, char *buf); + + void * (JNICALL *GetPrimitiveArrayCritical) + (JNIEnv *env, jarray array, jboolean *isCopy); + void (JNICALL *ReleasePrimitiveArrayCritical) + (JNIEnv *env, jarray array, void *carray, jint mode); + + const jchar * (JNICALL *GetStringCritical) + (JNIEnv *env, jstring string, jboolean *isCopy); + void (JNICALL *ReleaseStringCritical) + (JNIEnv *env, jstring string, const jchar *cstring); + + jweak (JNICALL *NewWeakGlobalRef) + (JNIEnv *env, jobject obj); + void (JNICALL *DeleteWeakGlobalRef) + (JNIEnv *env, jweak ref); + + jboolean (JNICALL *ExceptionCheck) + (JNIEnv *env); + + jobject (JNICALL *NewDirectByteBuffer) + (JNIEnv* env, void* address, jlong capacity); + void* (JNICALL *GetDirectBufferAddress) + (JNIEnv* env, jobject buf); + jlong (JNICALL *GetDirectBufferCapacity) + (JNIEnv* env, jobject buf); + + /* New JNI 1.6 Features */ + + jobjectRefType (JNICALL *GetObjectRefType) + (JNIEnv* env, jobject obj); +}; + +/* + * We use inlined functions for C++ so that programmers can write: + * + * env->FindClass("java/lang/String") + * + * in C++ rather than: + * + * (*env)->FindClass(env, "java/lang/String") + * + * in C. + */ + +struct JNIEnv_ { + const struct JNINativeInterface_ *functions; +#ifdef __cplusplus + + jint GetVersion() { + return functions->GetVersion(this); + } + jclass DefineClass(const char *name, jobject loader, const jbyte *buf, + jsize len) { + return functions->DefineClass(this, name, loader, buf, len); + } + jclass FindClass(const char *name) { + return functions->FindClass(this, name); + } + jmethodID FromReflectedMethod(jobject method) { + return functions->FromReflectedMethod(this,method); + } + jfieldID FromReflectedField(jobject field) { + return functions->FromReflectedField(this,field); + } + + jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic) { + return functions->ToReflectedMethod(this, cls, methodID, isStatic); + } + + jclass GetSuperclass(jclass sub) { + return functions->GetSuperclass(this, sub); + } + jboolean IsAssignableFrom(jclass sub, jclass sup) { + return functions->IsAssignableFrom(this, sub, sup); + } + + jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic) { + return functions->ToReflectedField(this,cls,fieldID,isStatic); + } + + jint Throw(jthrowable obj) { + return functions->Throw(this, obj); + } + jint ThrowNew(jclass clazz, const char *msg) { + return functions->ThrowNew(this, clazz, msg); + } + jthrowable ExceptionOccurred() { + return functions->ExceptionOccurred(this); + } + void ExceptionDescribe() { + functions->ExceptionDescribe(this); + } + void ExceptionClear() { + functions->ExceptionClear(this); + } + void FatalError(const char *msg) { + functions->FatalError(this, msg); + } + + jint PushLocalFrame(jint capacity) { + return functions->PushLocalFrame(this,capacity); + } + jobject PopLocalFrame(jobject result) { + return functions->PopLocalFrame(this,result); + } + + jobject NewGlobalRef(jobject lobj) { + return functions->NewGlobalRef(this,lobj); + } + void DeleteGlobalRef(jobject gref) { + functions->DeleteGlobalRef(this,gref); + } + void DeleteLocalRef(jobject obj) { + functions->DeleteLocalRef(this, obj); + } + + jboolean IsSameObject(jobject obj1, jobject obj2) { + return functions->IsSameObject(this,obj1,obj2); + } + + jobject NewLocalRef(jobject ref) { + return functions->NewLocalRef(this,ref); + } + jint EnsureLocalCapacity(jint capacity) { + return functions->EnsureLocalCapacity(this,capacity); + } + + jobject AllocObject(jclass clazz) { + return functions->AllocObject(this,clazz); + } + jobject NewObject(jclass clazz, jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args, methodID); + result = functions->NewObjectV(this,clazz,methodID,args); + va_end(args); + return result; + } + jobject NewObjectV(jclass clazz, jmethodID methodID, + va_list args) { + return functions->NewObjectV(this,clazz,methodID,args); + } + jobject NewObjectA(jclass clazz, jmethodID methodID, + const jvalue *args) { + return functions->NewObjectA(this,clazz,methodID,args); + } + + jclass GetObjectClass(jobject obj) { + return functions->GetObjectClass(this,obj); + } + jboolean IsInstanceOf(jobject obj, jclass clazz) { + return functions->IsInstanceOf(this,obj,clazz); + } + + jmethodID GetMethodID(jclass clazz, const char *name, + const char *sig) { + return functions->GetMethodID(this,clazz,name,sig); + } + + jobject CallObjectMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallObjectMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jobject CallObjectMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallObjectMethodV(this,obj,methodID,args); + } + jobject CallObjectMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallObjectMethodA(this,obj,methodID,args); + } + + jboolean CallBooleanMethod(jobject obj, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallBooleanMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jboolean CallBooleanMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallBooleanMethodV(this,obj,methodID,args); + } + jboolean CallBooleanMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallBooleanMethodA(this,obj,methodID, args); + } + + jbyte CallByteMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallByteMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jbyte CallByteMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallByteMethodV(this,obj,methodID,args); + } + jbyte CallByteMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallByteMethodA(this,obj,methodID,args); + } + + jchar CallCharMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallCharMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jchar CallCharMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallCharMethodV(this,obj,methodID,args); + } + jchar CallCharMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallCharMethodA(this,obj,methodID,args); + } + + jshort CallShortMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallShortMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jshort CallShortMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallShortMethodV(this,obj,methodID,args); + } + jshort CallShortMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallShortMethodA(this,obj,methodID,args); + } + + jint CallIntMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallIntMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jint CallIntMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallIntMethodV(this,obj,methodID,args); + } + jint CallIntMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallIntMethodA(this,obj,methodID,args); + } + + jlong CallLongMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallLongMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jlong CallLongMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallLongMethodV(this,obj,methodID,args); + } + jlong CallLongMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallLongMethodA(this,obj,methodID,args); + } + + jfloat CallFloatMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallFloatMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jfloat CallFloatMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallFloatMethodV(this,obj,methodID,args); + } + jfloat CallFloatMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallFloatMethodA(this,obj,methodID,args); + } + + jdouble CallDoubleMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallDoubleMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jdouble CallDoubleMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallDoubleMethodV(this,obj,methodID,args); + } + jdouble CallDoubleMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallDoubleMethodA(this,obj,methodID,args); + } + + void CallVoidMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallVoidMethodV(this,obj,methodID,args); + va_end(args); + } + void CallVoidMethodV(jobject obj, jmethodID methodID, + va_list args) { + functions->CallVoidMethodV(this,obj,methodID,args); + } + void CallVoidMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + functions->CallVoidMethodA(this,obj,methodID,args); + } + + jobject CallNonvirtualObjectMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallNonvirtualObjectMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jobject CallNonvirtualObjectMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualObjectMethodV(this,obj,clazz, + methodID,args); + } + jobject CallNonvirtualObjectMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualObjectMethodA(this,obj,clazz, + methodID,args); + } + + jboolean CallNonvirtualBooleanMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallNonvirtualBooleanMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jboolean CallNonvirtualBooleanMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualBooleanMethodV(this,obj,clazz, + methodID,args); + } + jboolean CallNonvirtualBooleanMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualBooleanMethodA(this,obj,clazz, + methodID, args); + } + + jbyte CallNonvirtualByteMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallNonvirtualByteMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jbyte CallNonvirtualByteMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualByteMethodV(this,obj,clazz, + methodID,args); + } + jbyte CallNonvirtualByteMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualByteMethodA(this,obj,clazz, + methodID,args); + } + + jchar CallNonvirtualCharMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallNonvirtualCharMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jchar CallNonvirtualCharMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualCharMethodV(this,obj,clazz, + methodID,args); + } + jchar CallNonvirtualCharMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualCharMethodA(this,obj,clazz, + methodID,args); + } + + jshort CallNonvirtualShortMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallNonvirtualShortMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jshort CallNonvirtualShortMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualShortMethodV(this,obj,clazz, + methodID,args); + } + jshort CallNonvirtualShortMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualShortMethodA(this,obj,clazz, + methodID,args); + } + + jint CallNonvirtualIntMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallNonvirtualIntMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jint CallNonvirtualIntMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualIntMethodV(this,obj,clazz, + methodID,args); + } + jint CallNonvirtualIntMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualIntMethodA(this,obj,clazz, + methodID,args); + } + + jlong CallNonvirtualLongMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallNonvirtualLongMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jlong CallNonvirtualLongMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualLongMethodV(this,obj,clazz, + methodID,args); + } + jlong CallNonvirtualLongMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualLongMethodA(this,obj,clazz, + methodID,args); + } + + jfloat CallNonvirtualFloatMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallNonvirtualFloatMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jfloat CallNonvirtualFloatMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + return functions->CallNonvirtualFloatMethodV(this,obj,clazz, + methodID,args); + } + jfloat CallNonvirtualFloatMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + return functions->CallNonvirtualFloatMethodA(this,obj,clazz, + methodID,args); + } + + jdouble CallNonvirtualDoubleMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallNonvirtualDoubleMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jdouble CallNonvirtualDoubleMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + return functions->CallNonvirtualDoubleMethodV(this,obj,clazz, + methodID,args); + } + jdouble CallNonvirtualDoubleMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + return functions->CallNonvirtualDoubleMethodA(this,obj,clazz, + methodID,args); + } + + void CallNonvirtualVoidMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); + va_end(args); + } + void CallNonvirtualVoidMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); + } + void CallNonvirtualVoidMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + functions->CallNonvirtualVoidMethodA(this,obj,clazz,methodID,args); + } + + jfieldID GetFieldID(jclass clazz, const char *name, + const char *sig) { + return functions->GetFieldID(this,clazz,name,sig); + } + + jobject GetObjectField(jobject obj, jfieldID fieldID) { + return functions->GetObjectField(this,obj,fieldID); + } + jboolean GetBooleanField(jobject obj, jfieldID fieldID) { + return functions->GetBooleanField(this,obj,fieldID); + } + jbyte GetByteField(jobject obj, jfieldID fieldID) { + return functions->GetByteField(this,obj,fieldID); + } + jchar GetCharField(jobject obj, jfieldID fieldID) { + return functions->GetCharField(this,obj,fieldID); + } + jshort GetShortField(jobject obj, jfieldID fieldID) { + return functions->GetShortField(this,obj,fieldID); + } + jint GetIntField(jobject obj, jfieldID fieldID) { + return functions->GetIntField(this,obj,fieldID); + } + jlong GetLongField(jobject obj, jfieldID fieldID) { + return functions->GetLongField(this,obj,fieldID); + } + jfloat GetFloatField(jobject obj, jfieldID fieldID) { + return functions->GetFloatField(this,obj,fieldID); + } + jdouble GetDoubleField(jobject obj, jfieldID fieldID) { + return functions->GetDoubleField(this,obj,fieldID); + } + + void SetObjectField(jobject obj, jfieldID fieldID, jobject val) { + functions->SetObjectField(this,obj,fieldID,val); + } + void SetBooleanField(jobject obj, jfieldID fieldID, + jboolean val) { + functions->SetBooleanField(this,obj,fieldID,val); + } + void SetByteField(jobject obj, jfieldID fieldID, + jbyte val) { + functions->SetByteField(this,obj,fieldID,val); + } + void SetCharField(jobject obj, jfieldID fieldID, + jchar val) { + functions->SetCharField(this,obj,fieldID,val); + } + void SetShortField(jobject obj, jfieldID fieldID, + jshort val) { + functions->SetShortField(this,obj,fieldID,val); + } + void SetIntField(jobject obj, jfieldID fieldID, + jint val) { + functions->SetIntField(this,obj,fieldID,val); + } + void SetLongField(jobject obj, jfieldID fieldID, + jlong val) { + functions->SetLongField(this,obj,fieldID,val); + } + void SetFloatField(jobject obj, jfieldID fieldID, + jfloat val) { + functions->SetFloatField(this,obj,fieldID,val); + } + void SetDoubleField(jobject obj, jfieldID fieldID, + jdouble val) { + functions->SetDoubleField(this,obj,fieldID,val); + } + + jmethodID GetStaticMethodID(jclass clazz, const char *name, + const char *sig) { + return functions->GetStaticMethodID(this,clazz,name,sig); + } + + jobject CallStaticObjectMethod(jclass clazz, jmethodID methodID, + ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallStaticObjectMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jobject CallStaticObjectMethodV(jclass clazz, jmethodID methodID, + va_list args) { + return functions->CallStaticObjectMethodV(this,clazz,methodID,args); + } + jobject CallStaticObjectMethodA(jclass clazz, jmethodID methodID, + const jvalue *args) { + return functions->CallStaticObjectMethodA(this,clazz,methodID,args); + } + + jboolean CallStaticBooleanMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallStaticBooleanMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jboolean CallStaticBooleanMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticBooleanMethodV(this,clazz,methodID,args); + } + jboolean CallStaticBooleanMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticBooleanMethodA(this,clazz,methodID,args); + } + + jbyte CallStaticByteMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallStaticByteMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jbyte CallStaticByteMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticByteMethodV(this,clazz,methodID,args); + } + jbyte CallStaticByteMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticByteMethodA(this,clazz,methodID,args); + } + + jchar CallStaticCharMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallStaticCharMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jchar CallStaticCharMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticCharMethodV(this,clazz,methodID,args); + } + jchar CallStaticCharMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticCharMethodA(this,clazz,methodID,args); + } + + jshort CallStaticShortMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallStaticShortMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jshort CallStaticShortMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticShortMethodV(this,clazz,methodID,args); + } + jshort CallStaticShortMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticShortMethodA(this,clazz,methodID,args); + } + + jint CallStaticIntMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallStaticIntMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jint CallStaticIntMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticIntMethodV(this,clazz,methodID,args); + } + jint CallStaticIntMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticIntMethodA(this,clazz,methodID,args); + } + + jlong CallStaticLongMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallStaticLongMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jlong CallStaticLongMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticLongMethodV(this,clazz,methodID,args); + } + jlong CallStaticLongMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticLongMethodA(this,clazz,methodID,args); + } + + jfloat CallStaticFloatMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallStaticFloatMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jfloat CallStaticFloatMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticFloatMethodV(this,clazz,methodID,args); + } + jfloat CallStaticFloatMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticFloatMethodA(this,clazz,methodID,args); + } + + jdouble CallStaticDoubleMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallStaticDoubleMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jdouble CallStaticDoubleMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticDoubleMethodV(this,clazz,methodID,args); + } + jdouble CallStaticDoubleMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticDoubleMethodA(this,clazz,methodID,args); + } + + void CallStaticVoidMethod(jclass cls, jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallStaticVoidMethodV(this,cls,methodID,args); + va_end(args); + } + void CallStaticVoidMethodV(jclass cls, jmethodID methodID, + va_list args) { + functions->CallStaticVoidMethodV(this,cls,methodID,args); + } + void CallStaticVoidMethodA(jclass cls, jmethodID methodID, + const jvalue * args) { + functions->CallStaticVoidMethodA(this,cls,methodID,args); + } + + jfieldID GetStaticFieldID(jclass clazz, const char *name, + const char *sig) { + return functions->GetStaticFieldID(this,clazz,name,sig); + } + jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticObjectField(this,clazz,fieldID); + } + jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticBooleanField(this,clazz,fieldID); + } + jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticByteField(this,clazz,fieldID); + } + jchar GetStaticCharField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticCharField(this,clazz,fieldID); + } + jshort GetStaticShortField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticShortField(this,clazz,fieldID); + } + jint GetStaticIntField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticIntField(this,clazz,fieldID); + } + jlong GetStaticLongField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticLongField(this,clazz,fieldID); + } + jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticFloatField(this,clazz,fieldID); + } + jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticDoubleField(this,clazz,fieldID); + } + + void SetStaticObjectField(jclass clazz, jfieldID fieldID, + jobject value) { + functions->SetStaticObjectField(this,clazz,fieldID,value); + } + void SetStaticBooleanField(jclass clazz, jfieldID fieldID, + jboolean value) { + functions->SetStaticBooleanField(this,clazz,fieldID,value); + } + void SetStaticByteField(jclass clazz, jfieldID fieldID, + jbyte value) { + functions->SetStaticByteField(this,clazz,fieldID,value); + } + void SetStaticCharField(jclass clazz, jfieldID fieldID, + jchar value) { + functions->SetStaticCharField(this,clazz,fieldID,value); + } + void SetStaticShortField(jclass clazz, jfieldID fieldID, + jshort value) { + functions->SetStaticShortField(this,clazz,fieldID,value); + } + void SetStaticIntField(jclass clazz, jfieldID fieldID, + jint value) { + functions->SetStaticIntField(this,clazz,fieldID,value); + } + void SetStaticLongField(jclass clazz, jfieldID fieldID, + jlong value) { + functions->SetStaticLongField(this,clazz,fieldID,value); + } + void SetStaticFloatField(jclass clazz, jfieldID fieldID, + jfloat value) { + functions->SetStaticFloatField(this,clazz,fieldID,value); + } + void SetStaticDoubleField(jclass clazz, jfieldID fieldID, + jdouble value) { + functions->SetStaticDoubleField(this,clazz,fieldID,value); + } + + jstring NewString(const jchar *unicode, jsize len) { + return functions->NewString(this,unicode,len); + } + jsize GetStringLength(jstring str) { + return functions->GetStringLength(this,str); + } + const jchar *GetStringChars(jstring str, jboolean *isCopy) { + return functions->GetStringChars(this,str,isCopy); + } + void ReleaseStringChars(jstring str, const jchar *chars) { + functions->ReleaseStringChars(this,str,chars); + } + + jstring NewStringUTF(const char *utf) { + return functions->NewStringUTF(this,utf); + } + jsize GetStringUTFLength(jstring str) { + return functions->GetStringUTFLength(this,str); + } + const char* GetStringUTFChars(jstring str, jboolean *isCopy) { + return functions->GetStringUTFChars(this,str,isCopy); + } + void ReleaseStringUTFChars(jstring str, const char* chars) { + functions->ReleaseStringUTFChars(this,str,chars); + } + + jsize GetArrayLength(jarray array) { + return functions->GetArrayLength(this,array); + } + + jobjectArray NewObjectArray(jsize len, jclass clazz, + jobject init) { + return functions->NewObjectArray(this,len,clazz,init); + } + jobject GetObjectArrayElement(jobjectArray array, jsize index) { + return functions->GetObjectArrayElement(this,array,index); + } + void SetObjectArrayElement(jobjectArray array, jsize index, + jobject val) { + functions->SetObjectArrayElement(this,array,index,val); + } + + jbooleanArray NewBooleanArray(jsize len) { + return functions->NewBooleanArray(this,len); + } + jbyteArray NewByteArray(jsize len) { + return functions->NewByteArray(this,len); + } + jcharArray NewCharArray(jsize len) { + return functions->NewCharArray(this,len); + } + jshortArray NewShortArray(jsize len) { + return functions->NewShortArray(this,len); + } + jintArray NewIntArray(jsize len) { + return functions->NewIntArray(this,len); + } + jlongArray NewLongArray(jsize len) { + return functions->NewLongArray(this,len); + } + jfloatArray NewFloatArray(jsize len) { + return functions->NewFloatArray(this,len); + } + jdoubleArray NewDoubleArray(jsize len) { + return functions->NewDoubleArray(this,len); + } + + jboolean * GetBooleanArrayElements(jbooleanArray array, jboolean *isCopy) { + return functions->GetBooleanArrayElements(this,array,isCopy); + } + jbyte * GetByteArrayElements(jbyteArray array, jboolean *isCopy) { + return functions->GetByteArrayElements(this,array,isCopy); + } + jchar * GetCharArrayElements(jcharArray array, jboolean *isCopy) { + return functions->GetCharArrayElements(this,array,isCopy); + } + jshort * GetShortArrayElements(jshortArray array, jboolean *isCopy) { + return functions->GetShortArrayElements(this,array,isCopy); + } + jint * GetIntArrayElements(jintArray array, jboolean *isCopy) { + return functions->GetIntArrayElements(this,array,isCopy); + } + jlong * GetLongArrayElements(jlongArray array, jboolean *isCopy) { + return functions->GetLongArrayElements(this,array,isCopy); + } + jfloat * GetFloatArrayElements(jfloatArray array, jboolean *isCopy) { + return functions->GetFloatArrayElements(this,array,isCopy); + } + jdouble * GetDoubleArrayElements(jdoubleArray array, jboolean *isCopy) { + return functions->GetDoubleArrayElements(this,array,isCopy); + } + + void ReleaseBooleanArrayElements(jbooleanArray array, + jboolean *elems, + jint mode) { + functions->ReleaseBooleanArrayElements(this,array,elems,mode); + } + void ReleaseByteArrayElements(jbyteArray array, + jbyte *elems, + jint mode) { + functions->ReleaseByteArrayElements(this,array,elems,mode); + } + void ReleaseCharArrayElements(jcharArray array, + jchar *elems, + jint mode) { + functions->ReleaseCharArrayElements(this,array,elems,mode); + } + void ReleaseShortArrayElements(jshortArray array, + jshort *elems, + jint mode) { + functions->ReleaseShortArrayElements(this,array,elems,mode); + } + void ReleaseIntArrayElements(jintArray array, + jint *elems, + jint mode) { + functions->ReleaseIntArrayElements(this,array,elems,mode); + } + void ReleaseLongArrayElements(jlongArray array, + jlong *elems, + jint mode) { + functions->ReleaseLongArrayElements(this,array,elems,mode); + } + void ReleaseFloatArrayElements(jfloatArray array, + jfloat *elems, + jint mode) { + functions->ReleaseFloatArrayElements(this,array,elems,mode); + } + void ReleaseDoubleArrayElements(jdoubleArray array, + jdouble *elems, + jint mode) { + functions->ReleaseDoubleArrayElements(this,array,elems,mode); + } + + void GetBooleanArrayRegion(jbooleanArray array, + jsize start, jsize len, jboolean *buf) { + functions->GetBooleanArrayRegion(this,array,start,len,buf); + } + void GetByteArrayRegion(jbyteArray array, + jsize start, jsize len, jbyte *buf) { + functions->GetByteArrayRegion(this,array,start,len,buf); + } + void GetCharArrayRegion(jcharArray array, + jsize start, jsize len, jchar *buf) { + functions->GetCharArrayRegion(this,array,start,len,buf); + } + void GetShortArrayRegion(jshortArray array, + jsize start, jsize len, jshort *buf) { + functions->GetShortArrayRegion(this,array,start,len,buf); + } + void GetIntArrayRegion(jintArray array, + jsize start, jsize len, jint *buf) { + functions->GetIntArrayRegion(this,array,start,len,buf); + } + void GetLongArrayRegion(jlongArray array, + jsize start, jsize len, jlong *buf) { + functions->GetLongArrayRegion(this,array,start,len,buf); + } + void GetFloatArrayRegion(jfloatArray array, + jsize start, jsize len, jfloat *buf) { + functions->GetFloatArrayRegion(this,array,start,len,buf); + } + void GetDoubleArrayRegion(jdoubleArray array, + jsize start, jsize len, jdouble *buf) { + functions->GetDoubleArrayRegion(this,array,start,len,buf); + } + + void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, + const jboolean *buf) { + functions->SetBooleanArrayRegion(this,array,start,len,buf); + } + void SetByteArrayRegion(jbyteArray array, jsize start, jsize len, + const jbyte *buf) { + functions->SetByteArrayRegion(this,array,start,len,buf); + } + void SetCharArrayRegion(jcharArray array, jsize start, jsize len, + const jchar *buf) { + functions->SetCharArrayRegion(this,array,start,len,buf); + } + void SetShortArrayRegion(jshortArray array, jsize start, jsize len, + const jshort *buf) { + functions->SetShortArrayRegion(this,array,start,len,buf); + } + void SetIntArrayRegion(jintArray array, jsize start, jsize len, + const jint *buf) { + functions->SetIntArrayRegion(this,array,start,len,buf); + } + void SetLongArrayRegion(jlongArray array, jsize start, jsize len, + const jlong *buf) { + functions->SetLongArrayRegion(this,array,start,len,buf); + } + void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, + const jfloat *buf) { + functions->SetFloatArrayRegion(this,array,start,len,buf); + } + void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, + const jdouble *buf) { + functions->SetDoubleArrayRegion(this,array,start,len,buf); + } + + jint RegisterNatives(jclass clazz, const JNINativeMethod *methods, + jint nMethods) { + return functions->RegisterNatives(this,clazz,methods,nMethods); + } + jint UnregisterNatives(jclass clazz) { + return functions->UnregisterNatives(this,clazz); + } + + jint MonitorEnter(jobject obj) { + return functions->MonitorEnter(this,obj); + } + jint MonitorExit(jobject obj) { + return functions->MonitorExit(this,obj); + } + + jint GetJavaVM(JavaVM **vm) { + return functions->GetJavaVM(this,vm); + } + + void GetStringRegion(jstring str, jsize start, jsize len, jchar *buf) { + functions->GetStringRegion(this,str,start,len,buf); + } + void GetStringUTFRegion(jstring str, jsize start, jsize len, char *buf) { + functions->GetStringUTFRegion(this,str,start,len,buf); + } + + void * GetPrimitiveArrayCritical(jarray array, jboolean *isCopy) { + return functions->GetPrimitiveArrayCritical(this,array,isCopy); + } + void ReleasePrimitiveArrayCritical(jarray array, void *carray, jint mode) { + functions->ReleasePrimitiveArrayCritical(this,array,carray,mode); + } + + const jchar * GetStringCritical(jstring string, jboolean *isCopy) { + return functions->GetStringCritical(this,string,isCopy); + } + void ReleaseStringCritical(jstring string, const jchar *cstring) { + functions->ReleaseStringCritical(this,string,cstring); + } + + jweak NewWeakGlobalRef(jobject obj) { + return functions->NewWeakGlobalRef(this,obj); + } + void DeleteWeakGlobalRef(jweak ref) { + functions->DeleteWeakGlobalRef(this,ref); + } + + jboolean ExceptionCheck() { + return functions->ExceptionCheck(this); + } + + jobject NewDirectByteBuffer(void* address, jlong capacity) { + return functions->NewDirectByteBuffer(this, address, capacity); + } + void* GetDirectBufferAddress(jobject buf) { + return functions->GetDirectBufferAddress(this, buf); + } + jlong GetDirectBufferCapacity(jobject buf) { + return functions->GetDirectBufferCapacity(this, buf); + } + jobjectRefType GetObjectRefType(jobject obj) { + return functions->GetObjectRefType(this, obj); + } + +#endif /* __cplusplus */ +}; + +typedef struct JavaVMOption { + char *optionString; + void *extraInfo; +} JavaVMOption; + +typedef struct JavaVMInitArgs { + jint version; + + jint nOptions; + JavaVMOption *options; + jboolean ignoreUnrecognized; +} JavaVMInitArgs; + +typedef struct JavaVMAttachArgs { + jint version; + + char *name; + jobject group; +} JavaVMAttachArgs; + +/* These will be VM-specific. */ + +#define JDK1_2 +#define JDK1_4 + +/* End VM-specific. */ + +struct JNIInvokeInterface_ { + void *reserved0; + void *reserved1; + void *reserved2; + + jint (JNICALL *DestroyJavaVM)(JavaVM *vm); + + jint (JNICALL *AttachCurrentThread)(JavaVM *vm, void **penv, void *args); + + jint (JNICALL *DetachCurrentThread)(JavaVM *vm); + + jint (JNICALL *GetEnv)(JavaVM *vm, void **penv, jint version); + + jint (JNICALL *AttachCurrentThreadAsDaemon)(JavaVM *vm, void **penv, void *args); +}; + +struct JavaVM_ { + const struct JNIInvokeInterface_ *functions; +#ifdef __cplusplus + + jint DestroyJavaVM() { + return functions->DestroyJavaVM(this); + } + jint AttachCurrentThread(void **penv, void *args) { + return functions->AttachCurrentThread(this, penv, args); + } + jint DetachCurrentThread() { + return functions->DetachCurrentThread(this); + } + + jint GetEnv(void **penv, jint version) { + return functions->GetEnv(this, penv, version); + } + jint AttachCurrentThreadAsDaemon(void **penv, void *args) { + return functions->AttachCurrentThreadAsDaemon(this, penv, args); + } +#endif +}; + +#ifdef _JNI_IMPLEMENTATION_ +#define _JNI_IMPORT_OR_EXPORT_ JNIEXPORT +#else +#define _JNI_IMPORT_OR_EXPORT_ JNIIMPORT +#endif +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_GetDefaultJavaVMInitArgs(void *args); + +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args); + +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_GetCreatedJavaVMs(JavaVM **, jsize, jsize *); + +/* Defined by native libraries. */ +JNIEXPORT jint JNICALL +JNI_OnLoad(JavaVM *vm, void *reserved); + +JNIEXPORT void JNICALL +JNI_OnUnload(JavaVM *vm, void *reserved); + +#define JNI_VERSION_1_1 0x00010001 +#define JNI_VERSION_1_2 0x00010002 +#define JNI_VERSION_1_4 0x00010004 +#define JNI_VERSION_1_6 0x00010006 + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* !_JAVASOFT_JNI_H_ */ + + + diff --git a/native/IdeaWin32/jni_md.h b/native/IdeaWin32/jni_md.h new file mode 100644 index 000000000000..9f0cfa463837 --- /dev/null +++ b/native/IdeaWin32/jni_md.h @@ -0,0 +1,19 @@ +/* + * @(#)jni_md.h 1.15 05/11/17 + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +#ifndef _JAVASOFT_JNI_MD_H_ +#define _JAVASOFT_JNI_MD_H_ + +#define JNIEXPORT __declspec(dllexport) +#define JNIIMPORT __declspec(dllimport) +#define JNICALL __stdcall + +typedef long jint; +typedef __int64 jlong; +typedef signed char jbyte; + +#endif /* !_JAVASOFT_JNI_MD_H_ */ diff --git a/native/IdeaWin32/jni_util.h b/native/IdeaWin32/jni_util.h new file mode 100644 index 000000000000..a1ae06ad4447 --- /dev/null +++ b/native/IdeaWin32/jni_util.h @@ -0,0 +1,347 @@ +/* + * Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +#ifndef JNI_UTIL_H +#define JNI_UTIL_H + +#include "jni.h" +#include "jlong.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This file contains utility functions that can be implemented in pure JNI. + * + * Caution: Callers of functions declared in this file should be + * particularly aware of the fact that these functions are convenience + * functions, and as such are often compound operations, each one of + * which may throw an exception. Therefore, the functions this file + * will often return silently if an exception has occured, and callers + * must check for exception themselves. + */ + +/* Throw a Java exception by name. Similar to SignalError. */ +JNIEXPORT void JNICALL +JNU_ThrowByName(JNIEnv *env, const char *name, const char *msg); + +/* Throw common exceptions */ +JNIEXPORT void JNICALL +JNU_ThrowNullPointerException(JNIEnv *env, const char *msg); + +JNIEXPORT void JNICALL +JNU_ThrowArrayIndexOutOfBoundsException(JNIEnv *env, const char *msg); + +JNIEXPORT void JNICALL +JNU_ThrowOutOfMemoryError(JNIEnv *env, const char *msg); + +JNIEXPORT void JNICALL +JNU_ThrowIllegalArgumentException(JNIEnv *env, const char *msg); + +JNIEXPORT void JNICALL +JNU_ThrowIllegalAccessError(JNIEnv *env, const char *msg); + +JNIEXPORT void JNICALL +JNU_ThrowIllegalAccessException(JNIEnv *env, const char *msg); + +JNIEXPORT void JNICALL +JNU_ThrowInternalError(JNIEnv *env, const char *msg); + +JNIEXPORT void JNICALL +JNU_ThrowIOException(JNIEnv *env, const char *msg); + +JNIEXPORT void JNICALL +JNU_ThrowNoSuchFieldException(JNIEnv *env, const char *msg); + +JNIEXPORT void JNICALL +JNU_ThrowNoSuchMethodException(JNIEnv *env, const char *msg); + +JNIEXPORT void JNICALL +JNU_ThrowClassNotFoundException(JNIEnv *env, const char *msg); + +JNIEXPORT void JNICALL +JNU_ThrowNumberFormatException(JNIEnv *env, const char *msg); + +JNIEXPORT void JNICALL +JNU_ThrowNoSuchFieldError(JNIEnv *env, const char *msg); + +JNIEXPORT void JNICALL +JNU_ThrowNoSuchMethodError(JNIEnv *env, const char *msg); + +JNIEXPORT void JNICALL +JNU_ThrowStringIndexOutOfBoundsException(JNIEnv *env, const char *msg); + +JNIEXPORT void JNICALL +JNU_ThrowInstantiationException(JNIEnv *env, const char *msg); + +/* Throw an exception by name, using the string returned by + * JVM_LastErrorString for the detail string. If the last-error + * string is NULL, use the given default detail string. + */ +JNIEXPORT void JNICALL +JNU_ThrowByNameWithLastError(JNIEnv *env, const char *name, + const char *defaultMessage); + +/* Throw an IOException, using the last-error string for the detail + * string. If the last-error string is NULL, use the given default + * detail string. + */ +JNIEXPORT void JNICALL +JNU_ThrowIOExceptionWithLastError(JNIEnv *env, const char *defaultDetail); + +/* Convert between Java strings and i18n C strings */ +JNIEXPORT jstring +NewStringPlatform(JNIEnv *env, const char *str); + +JNIEXPORT const char * +GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy); + +JNIEXPORT jstring JNICALL +JNU_NewStringPlatform(JNIEnv *env, const char *str); + +JNIEXPORT const char * JNICALL +JNU_GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy); + +JNIEXPORT void JNICALL +JNU_ReleaseStringPlatformChars(JNIEnv *env, jstring jstr, const char *str); + +/* Class constants */ +JNIEXPORT jclass JNICALL +JNU_ClassString(JNIEnv *env); + +JNIEXPORT jclass JNICALL +JNU_ClassClass(JNIEnv *env); + +JNIEXPORT jclass JNICALL +JNU_ClassObject(JNIEnv *env); + +JNIEXPORT jclass JNICALL +JNU_ClassThrowable(JNIEnv *env); + +/* Copy count number of arguments from src to dst. Array bounds + * and ArrayStoreException are checked. + */ +JNIEXPORT jint JNICALL +JNU_CopyObjectArray(JNIEnv *env, jobjectArray dst, jobjectArray src, + jint count); + +/* Invoke a object-returning static method, based on class name, + * method name, and signature string. + * + * The caller should check for exceptions by setting hasException + * argument. If the caller is not interested in whether an exception + * has occurred, pass in NULL. + */ +JNIEXPORT jvalue JNICALL +JNU_CallStaticMethodByName(JNIEnv *env, + jboolean *hasException, + const char *class_name, + const char *name, + const char *signature, + ...); + +/* Invoke an instance method by name. + */ +JNIEXPORT jvalue JNICALL +JNU_CallMethodByName(JNIEnv *env, + jboolean *hasException, + jobject obj, + const char *name, + const char *signature, + ...); + +JNIEXPORT jvalue JNICALL +JNU_CallMethodByNameV(JNIEnv *env, + jboolean *hasException, + jobject obj, + const char *name, + const char *signature, + va_list args); + +/* Construct a new object of class, specifying the class by name, + * and specififying which constructor to run and what arguments to + * pass to it. + * + * The method will return an initialized instance if successful. + * It will return NULL if an error has occured (for example if + * it ran out of memory) and the appropriate Java exception will + * have been thrown. + */ +JNIEXPORT jobject JNICALL +JNU_NewObjectByName(JNIEnv *env, const char *class_name, + const char *constructor_sig, ...); + +/* returns: + * 0: object is not an instance of the class named by classname. + * 1: object is an instance of the class named by classname. + * -1: the class named by classname cannot be found. An exception + * has been thrown. + */ +JNIEXPORT jint JNICALL +JNU_IsInstanceOfByName(JNIEnv *env, jobject object, char *classname); + + +/* Get or set class and instance fields. + * Note that set functions take a variable number of arguments, + * but only one argument of the appropriate type can be passed. + * For example, to set an integer field i to 100: + * + * JNU_SetFieldByName(env, &exc, obj, "i", "I", 100); + * + * To set a float field f to 12.3: + * + * JNU_SetFieldByName(env, &exc, obj, "f", "F", 12.3); + * + * The caller should check for exceptions by setting hasException + * argument. If the caller is not interested in whether an exception + * has occurred, pass in NULL. + */ +JNIEXPORT jvalue JNICALL +JNU_GetFieldByName(JNIEnv *env, + jboolean *hasException, + jobject obj, + const char *name, + const char *sig); +JNIEXPORT void JNICALL +JNU_SetFieldByName(JNIEnv *env, + jboolean *hasException, + jobject obj, + const char *name, + const char *sig, + ...); + +JNIEXPORT jvalue JNICALL +JNU_GetStaticFieldByName(JNIEnv *env, + jboolean *hasException, + const char *classname, + const char *name, + const char *sig); +JNIEXPORT void JNICALL +JNU_SetStaticFieldByName(JNIEnv *env, + jboolean *hasException, + const char *classname, + const char *name, + const char *sig, + ...); + + +/* + * Calls the .equals method. + */ +JNIEXPORT jboolean JNICALL +JNU_Equals(JNIEnv *env, jobject object1, jobject object2); + + +/************************************************************************ + * Thread calls + * + * Convenience thread-related calls on the java.lang.Object class. + */ + +JNIEXPORT void JNICALL +JNU_MonitorWait(JNIEnv *env, jobject object, jlong timeout); + +JNIEXPORT void JNICALL +JNU_Notify(JNIEnv *env, jobject object); + +JNIEXPORT void JNICALL +JNU_NotifyAll(JNIEnv *env, jobject object); + + +/************************************************************************ + * Miscellaneous utilities used by the class libraries + */ + +#define IS_NULL(obj) ((obj) == NULL) +#define JNU_IsNull(env,obj) ((obj) == NULL) + + +/************************************************************************ + * Debugging utilities + */ + +JNIEXPORT void JNICALL +JNU_PrintString(JNIEnv *env, char *hdr, jstring string); + +JNIEXPORT void JNICALL +JNU_PrintClass(JNIEnv *env, char *hdr, jobject object); + +JNIEXPORT jstring JNICALL +JNU_ToString(JNIEnv *env, jobject object); + +/* + * Package shorthand for use by native libraries + */ +#define JNU_JAVAPKG "java/lang/" +#define JNU_JAVAIOPKG "java/io/" +#define JNU_JAVANETPKG "java/net/" + +/* + * Check if the current thread is attached to the VM, and returns + * the JNIEnv of the specified version if the thread is attached. + * + * If the current thread is not attached, this function returns 0. + * + * If the current thread is attached, this function returns the + * JNI environment, or returns (void *)JNI_ERR if the specified + * version is not supported. + */ +JNIEXPORT void * JNICALL +JNU_GetEnv(JavaVM *vm, jint version); + +/* + * Warning free access to pointers stored in Java long fields. + */ +#define JNU_GetLongFieldAsPtr(env,obj,id) \ + (jlong_to_ptr((*(env))->GetLongField((env),(obj),(id)))) +#define JNU_SetLongFieldFromPtr(env,obj,id,val) \ + (*(env))->SetLongField((env),(obj),(id),ptr_to_jlong(val)) + +/* + * Internal use only. + */ +enum { + NO_ENCODING_YET = 0, /* "sun.jnu.encoding" not yet set */ + NO_FAST_ENCODING, /* Platform encoding is not fast */ + FAST_8859_1, /* ISO-8859-1 */ + FAST_CP1252, /* MS-DOS Cp1252 */ + FAST_646_US /* US-ASCII : ISO646-US */ +}; + +jstring nativeNewStringPlatform(JNIEnv *env, const char *str); + +char* nativeGetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy); + +int getFastEncoding(); + +void initializeEncoding(); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* JNI_UTIL_H */ diff --git a/native/IdeaWin32/stdafx.cpp b/native/IdeaWin32/stdafx.cpp new file mode 100644 index 000000000000..9a99d3a2049d --- /dev/null +++ b/native/IdeaWin32/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// IdeaWin32.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/native/IdeaWin32/stdafx.h b/native/IdeaWin32/stdafx.h new file mode 100644 index 000000000000..2bdfa89d3315 --- /dev/null +++ b/native/IdeaWin32/stdafx.h @@ -0,0 +1,28 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef WINVER // Allow use of features specific to Windows XP or later. +#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. +#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. +#endif + +#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later. +#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE. +#endif + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include diff --git a/platform/lang-api/src/com/intellij/analysis/AnalysisScope.java b/platform/lang-api/src/com/intellij/analysis/AnalysisScope.java index 81f2f738649b..be517d3acad6 100644 --- a/platform/lang-api/src/com/intellij/analysis/AnalysisScope.java +++ b/platform/lang-api/src/com/intellij/analysis/AnalysisScope.java @@ -131,6 +131,7 @@ public class AnalysisScope { myModules = null; myScope = scope; myType = CUSTOM; + mySearchInLibraries = scope instanceof GlobalSearchScope && ((GlobalSearchScope)scope).isSearchInLibraries(); } public AnalysisScope(@NotNull Project project, @NotNull Collection virtualFiles) { @@ -198,6 +199,11 @@ public class AnalysisScope { public boolean contains(VirtualFile file) { if (myFilesSet == null) { + if (myType == CUSTOM) { + // optimization + if (myScope instanceof GlobalSearchScope) return ((GlobalSearchScope)myScope).contains(file); + if (myScope instanceof LocalSearchScope) return ((LocalSearchScope)myScope).isInScope(file); + } if (myType == PROJECT) { //optimization final ProjectFileIndex index = ProjectRootManager.getInstance(myProject).getFileIndex(); return index.isInContent(file) && (myIncludeTestSource || !index.isInTestSourceContent(file)); diff --git a/platform/lang-api/src/com/intellij/codeInsight/intention/IntentionActionBean.java b/platform/lang-api/src/com/intellij/codeInsight/intention/IntentionActionBean.java index ef2fdbd85d19..d1160e264663 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/intention/IntentionActionBean.java +++ b/platform/lang-api/src/com/intellij/codeInsight/intention/IntentionActionBean.java @@ -19,6 +19,7 @@ package com.intellij.codeInsight.intention; import com.intellij.CommonBundle; import com.intellij.ide.plugins.IdeaPluginDescriptor; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.CustomLoadingExtensionPointBean; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; @@ -29,7 +30,7 @@ import java.util.Locale; import java.util.ResourceBundle; public class IntentionActionBean extends CustomLoadingExtensionPointBean { - + private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.intention.IntentionActionBean"); @Tag("className") public String className; @Tag("category") @@ -45,6 +46,9 @@ public class IntentionActionBean extends CustomLoadingExtensionPointBean { public String[] getCategories() { if (categoryKey != null) { final String baseName = bundleName != null ? bundleName : ((IdeaPluginDescriptor)myPluginDescriptor).getResourceBundleBaseName(); + if (baseName == null) { + LOG.error("No resource bundle specified for "+myPluginDescriptor); + } final ResourceBundle bundle = ResourceBundle.getBundle(baseName, Locale.getDefault(), myPluginDescriptor.getPluginClassLoader()); final String[] keys = categoryKey.split("/"); diff --git a/platform/lang-impl/src/com/intellij/analysis/AnalysisUIOptions.java b/platform/lang-impl/src/com/intellij/analysis/AnalysisUIOptions.java index 01b6967f7600..78c3d653d86c 100644 --- a/platform/lang-impl/src/com/intellij/analysis/AnalysisUIOptions.java +++ b/platform/lang-impl/src/com/intellij/analysis/AnalysisUIOptions.java @@ -54,7 +54,7 @@ public class AnalysisUIOptions implements PersistentStateComponent matchingTemplates) { ArrayList array = new ArrayList(); - for (TemplateImpl template: matchingTemplates) { + for (TemplateImpl template : matchingTemplates) { array.add(new LookupItem(template, template.getKey())); } LookupElement[] items = array.toArray(new LookupElement[array.size()]); - final LookupImpl lookup = (LookupImpl) LookupManager.getInstance(project).createLookup(editor, items, prefix, LookupArranger.DEFAULT); - lookup.addLookupListener( - new LookupAdapter() { - public void itemSelected(LookupEvent event) { - final LookupElement lookupElement = event.getItem(); - if (lookupElement != null) { - final TemplateImpl template = (TemplateImpl)lookupElement.getObject(); - new WriteCommandAction(project) { - protected void run(Result result) throws Throwable { - ((TemplateManagerImpl) TemplateManager.getInstance(project)).startTemplateWithPrefix(editor, template, null); - } - }.execute(); - } - } - } - ); + final LookupImpl lookup = (LookupImpl)LookupManager.getInstance(project).createLookup(editor, items, prefix, LookupArranger.DEFAULT); + lookup.addLookupListener(new MyLookupAdapter(project, editor, null)); + lookup.show(); + } + + private static String computePrefix(TemplateImpl template, String argument) { + String key = template.getKey(); + if (argument == null) { + return key; + } + if (key.length() > 0 && Character.isJavaIdentifierPart(key.charAt(key.length() - 1))) { + return key + ' ' + argument; + } + return key + argument; + } + + public static void showTemplatesLookup(final Project project, + final Editor editor, + Map template2Argument) { + ArrayList array = new ArrayList(); + for (TemplateImpl template : template2Argument.keySet()) { + String argument = template2Argument.get(template); + String prefix = computePrefix(template, argument); + LookupItem item = new LookupItem(template, prefix); + item.setPrefixMatcher(new CamelHumpMatcher(prefix)); + array.add(item); + } + LookupElement[] items = array.toArray(new LookupElement[array.size()]); + + final LookupImpl lookup = (LookupImpl)LookupManager.getInstance(project).createLookup(editor, items, null, LookupArranger.DEFAULT); + lookup.addLookupListener(new MyLookupAdapter(project, editor, template2Argument)); lookup.show(); } @@ -93,10 +109,10 @@ public class ListTemplatesHandler implements CodeInsightActionHandler{ return true; } - private static String getPrefix(Document document, int offset) { + private String getPrefix(Document document, int offset) { CharSequence chars = document.getCharsSequence(); int start = offset; - while(true){ + while (true) { if (start == 0) break; char c = chars.charAt(start - 1); if (!isInPrefix(c)) break; @@ -105,7 +121,29 @@ public class ListTemplatesHandler implements CodeInsightActionHandler{ return chars.subSequence(start, offset).toString(); } - private static boolean isInPrefix(final char c) { + private boolean isInPrefix(final char c) { return Character.isJavaIdentifierPart(c) || c == '.'; } + + private static class MyLookupAdapter extends LookupAdapter { + private final Project myProject; + private final Editor myEditor; + private final Map myTemplate2Argument; + + public MyLookupAdapter(Project project, Editor editor, Map template2Argument) { + myProject = project; + myEditor = editor; + myTemplate2Argument = template2Argument; + } + + public void itemSelected(LookupEvent event) { + final TemplateImpl template = (TemplateImpl)event.getItem().getObject(); + final String argument = myTemplate2Argument != null ? myTemplate2Argument.get(template) : null; + new WriteCommandAction(myProject) { + protected void run(Result result) throws Throwable { + ((TemplateManagerImpl)TemplateManager.getInstance(myProject)).startTemplateWithPrefix(myEditor, template, null, argument); + } + }.execute(); + } + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateImpl.java index 0eeec65d928f..dac35a95ccd9 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateImpl.java @@ -88,6 +88,7 @@ public class TemplateImpl extends Template implements SchemeElement { @NonNls public static final String SELECTION = "SELECTION"; @NonNls public static final String SELECTION_START = "SELECTION_START"; @NonNls public static final String SELECTION_END = "SELECTION_END"; + @NonNls public static final String ARG = "ARG"; public static final Set INTERNAL_VARS_SET = new HashSet(Arrays.asList( END, SELECTION, SELECTION_START, SELECTION_END)); @@ -381,6 +382,13 @@ public class TemplateImpl extends Template implements SchemeElement { return false; } + public boolean hasArgument() { + for (Variable v : myVariables) { + if (v.getName().equals(ARG)) return true; + } + return false; + } + public void setId(final String id) { myId = id; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateManagerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateManagerImpl.java index cefc84993e89..566327bb87ca 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateManagerImpl.java @@ -36,6 +36,7 @@ import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiUtilBase; import com.intellij.util.PairProcessor; +import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -59,7 +60,8 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo myDisposables.clear(); } - public void initComponent() { } + public void initComponent() { + } public void projectClosed() { } @@ -133,12 +135,17 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo startTemplate(editor, selectionString, template, null, null); } - public void startTemplate(@NotNull Editor editor, @NotNull Template template, TemplateEditingListener listener, + public void startTemplate(@NotNull Editor editor, + @NotNull Template template, + TemplateEditingListener listener, final PairProcessor processor) { startTemplate(editor, null, template, listener, processor); } - private void startTemplate(final Editor editor, final String selectionString, final Template template, TemplateEditingListener listener, + private void startTemplate(final Editor editor, + final String selectionString, + final Template template, + TemplateEditingListener listener, final PairProcessor processor) { final TemplateState templateState = initTemplateState(editor); @@ -147,23 +154,21 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo if (listener != null) { templateState.addTemplateStateListener(listener); } - CommandProcessor.getInstance().executeCommand( - myProject, new Runnable() { - public void run() { - if (selectionString != null) { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - public void run() { - EditorModificationUtil.deleteSelectedText(editor); - } - }); - } else { - editor.getSelectionModel().removeSelection(); - } - templateState.start((TemplateImpl) template, processor); + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + if (selectionString != null) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + EditorModificationUtil.deleteSelectedText(editor); + } + }); } - }, - CodeInsightBundle.message("insert.code.template.command"), null - ); + else { + editor.getSelectionModel().removeSelection(); + } + templateState.start((TemplateImpl)template, processor, null); + } + }, CodeInsightBundle.message("insert.code.template.command"), null); if (shouldSkipInTests()) { if (!templateState.isFinished()) templateState.gotoEnd(); @@ -178,6 +183,23 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo startTemplate(editor, null, template, listener, null); } + private static int passArgumentBack(CharSequence text, int caretOffset) { + int i = caretOffset - 1; + for (; i >= 0; i--) { + char c = text.charAt(i); + if (!Character.isJavaIdentifierPart(c)) { + break; + } + } + return i + 1; + } + + private static void addToMap(@NotNull Map map, @NotNull Collection keys, U value) { + for (T key : keys) { + map.put(key, value); + } + } + public boolean startTemplate(final Editor editor, char shortcutChar, final PairProcessor processor) { final Document document = editor.getDocument(); PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, myProject); @@ -185,10 +207,69 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo TemplateSettings templateSettings = TemplateSettings.getInstance(); CharSequence text = document.getCharsSequence(); + final int caretOffset = editor.getCaretModel().getOffset(); - String key = null; + List candidatesWithoutArgument = findMatchingTemplates(text, caretOffset, shortcutChar, templateSettings, false); + + int argumentOffset = passArgumentBack(text, caretOffset); + String argument = null; + if (argumentOffset >= 0) { + argument = text.subSequence(argumentOffset, caretOffset).toString(); + if (argumentOffset > 0 && text.charAt(argumentOffset - 1) == ' ') { + if (argumentOffset - 2 >= 0 && Character.isJavaIdentifierPart(text.charAt(argumentOffset - 2))) { + argumentOffset--; + } + } + } + List candidatesWithArgument = findMatchingTemplates(text, argumentOffset, shortcutChar, templateSettings, true); + + if (candidatesWithArgument.isEmpty() && candidatesWithoutArgument.isEmpty()) return false; + + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + PsiDocumentManager.getInstance(myProject).commitDocument(document); + } + }, "", null); + + candidatesWithoutArgument = filterApplicableCandidates(file, caretOffset, candidatesWithoutArgument); + candidatesWithArgument = filterApplicableCandidates(file, argumentOffset, candidatesWithArgument); + Map candidate2Argument = new HashMap(); + addToMap(candidate2Argument, candidatesWithoutArgument, null); + addToMap(candidate2Argument, candidatesWithArgument, argument); + + if (candidate2Argument.isEmpty()) { + return false; + } + if (!FileDocumentManager.getInstance().requestWriting(editor.getDocument(), myProject)) { + return false; + } + + if (candidate2Argument.size() == 1) { + TemplateImpl template = candidate2Argument.keySet().iterator().next(); + if (candidatesWithoutArgument.size() == 1) { + int templateStart = caretOffset - template.getKey().length(); + startTemplateWithPrefix(editor, template, templateStart, processor, null); + } + else { + int templateStart = argumentOffset - template.getKey().length(); + startTemplateWithPrefix(editor, template, templateStart, processor, argument); + } + } + else { + ListTemplatesHandler.showTemplatesLookup(myProject, editor, candidate2Argument); + } + + return true; + } + + private static List findMatchingTemplates(CharSequence text, + int caretOffset, + char shortcutChar, + TemplateSettings settings, + boolean hasArgument) { + String key; List candidates = Collections.emptyList(); - for (int i = templateSettings.getMaxKeyLength(); i >= 1 ; i--) { + for (int i = settings.getMaxKeyLength(); i >= 1; i--) { int wordStart = caretOffset - i; if (wordStart < 0) { continue; @@ -200,63 +281,47 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo } } - candidates = templateSettings.collectMatchingCandidates(key, shortcutChar); + candidates = settings.collectMatchingCandidates(key, shortcutChar, hasArgument); if (!candidates.isEmpty()) break; } - - if (candidates.isEmpty()) return false; - - CommandProcessor.getInstance().executeCommand( - myProject, new Runnable() { - public void run() { - PsiDocumentManager.getInstance(myProject).commitDocument(document); - } - }, - "", null - ); - - candidates = filterApplicableCandidates(file, caretOffset - key.length(), candidates); - if (candidates.isEmpty()) { - return false; - } - if (!FileDocumentManager.getInstance().requestWriting(editor.getDocument(), myProject)) { - return false; - } - - if (candidates.size() == 1) { - TemplateImpl template = candidates.get(0); - startTemplateWithPrefix(editor, template, processor); - } - else { - ListTemplatesHandler.showTemplatesLookup(myProject, editor, key, candidates); - } - - return true; + return candidates; } - public void startTemplateWithPrefix(final Editor editor, final TemplateImpl template, @Nullable final PairProcessor processor) { + public void startTemplateWithPrefix(final Editor editor, + final TemplateImpl template, + @Nullable final PairProcessor processor, + @Nullable String argument) { + final int caretOffset = editor.getCaretModel().getOffset(); + int startOffset = caretOffset - template.getKey().length(); + if (argument != null) { + startOffset -= argument.length(); + } + startTemplateWithPrefix(editor, template, startOffset, processor, argument); + } + + public void startTemplateWithPrefix(final Editor editor, + final TemplateImpl template, + final int templateStart, + @Nullable final PairProcessor processor, + @Nullable final String argument) { final int caretOffset = editor.getCaretModel().getOffset(); - final int wordStart = caretOffset - template.getKey().length(); final TemplateState templateState = initTemplateState(editor); CommandProcessor commandProcessor = CommandProcessor.getInstance(); - commandProcessor.executeCommand( - myProject, new Runnable() { - public void run() { - editor.getDocument().deleteString(wordStart, caretOffset); - editor.getCaretModel().moveToOffset(wordStart); - editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); - editor.getSelectionModel().removeSelection(); - templateState.start(template, processor); - } - }, - CodeInsightBundle.message("insert.code.template.command"), null - ); + commandProcessor.executeCommand(myProject, new Runnable() { + public void run() { + editor.getDocument().deleteString(templateStart, caretOffset); + editor.getCaretModel().moveToOffset(templateStart); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + editor.getSelectionModel().removeSelection(); + templateState.start(template, processor, argument); + } + }, CodeInsightBundle.message("insert.code.template.command"), null); } - private static List filterApplicableCandidates(PsiFile file, int offset, List candidates) { + private static List filterApplicableCandidates(PsiFile file, int caretOffset, List candidates) { List result = new ArrayList(); for (TemplateImpl candidate : candidates) { - if (isApplicable(file, offset, candidate)) { + if (isApplicable(file, caretOffset - candidate.getKey().length(), candidate)) { result.add(candidate); } } @@ -266,16 +331,20 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo public TemplateContextType getContextType(@NotNull PsiFile file, int offset) { final TemplateContextType[] typeCollection = getAllContextTypes(); LinkedList userDefinedExtensionsFirst = new LinkedList(); - for(TemplateContextType contextType: typeCollection) { - if (contextType.getClass().getName().startsWith("com.intellij.codeInsight.template")) userDefinedExtensionsFirst.addLast(contextType); - else userDefinedExtensionsFirst.addFirst(contextType); + for (TemplateContextType contextType : typeCollection) { + if (contextType.getClass().getName().startsWith("com.intellij.codeInsight.template")) { + userDefinedExtensionsFirst.addLast(contextType); + } + else { + userDefinedExtensionsFirst.addFirst(contextType); + } } - for(TemplateContextType contextType: userDefinedExtensionsFirst) { + for (TemplateContextType contextType : userDefinedExtensionsFirst) { if (contextType.isInContext(file, offset)) { return contextType; } } - assert false: "OtherContextType should match any context"; + assert false : "OtherContextType should match any context"; return null; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java index c5ddf57fc5bb..a1f72df86d46 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java @@ -673,7 +673,7 @@ public class TemplateSettings implements PersistentStateComponent, Expo return mySchemesManager.getAllSchemes(); } - public List collectMatchingCandidates(String key, char shortcutChar) { + public List collectMatchingCandidates(String key, char shortcutChar, boolean hasArgument) { final Collection templates = getTemplates(key); List candidates = new ArrayList(); for (TemplateImpl template : templates) { @@ -686,6 +686,9 @@ public class TemplateSettings implements PersistentStateComponent, Expo if (template.isSelectionTemplate()) { continue; } + if (hasArgument && !template.hasArgument()) { + continue; + } candidates.add(template); } return candidates; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java index c49899a94100..98b09560cae8 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java @@ -71,6 +71,7 @@ public class TemplateState implements Disposable { private TemplateImpl myTemplate; private TemplateSegments mySegments = null; + private String myArgument; private RangeMarker myTemplateRange = null; private final ArrayList myTabStopHighlighters = new ArrayList(); @@ -106,6 +107,7 @@ public class TemplateState implements Disposable { myCommandListener = new CommandAdapter() { boolean started = false; + public void commandStarted(CommandEvent event) { if (myEditor != null) { final int offset = myEditor.getCaretModel().getOffset(); @@ -170,6 +172,9 @@ public class TemplateState implements Disposable { if (variableName.equals(TemplateImpl.END)) { return new TextResult(""); } + if (variableName.equals(TemplateImpl.ARG) && myArgument != null) { + return new TextResult(myArgument); + } CharSequence text = myDocument.getCharsSequence(); int segmentNumber = myTemplate.getVariableSegmentNumber(variableName); @@ -230,45 +235,43 @@ public class TemplateState implements Disposable { } } - public void start(TemplateImpl template, @Nullable final PairProcessor processor) { + public void start(TemplateImpl template, @Nullable final PairProcessor processor, @Nullable String argument) { PsiDocumentManager.getInstance(myProject).commitAllDocuments(); myProcessor = processor; - final DocumentReference[] refs = myDocument == null - ? null - : new DocumentReference[] {DocumentReferenceManager.getInstance().create(myDocument) }; + final DocumentReference[] refs = + myDocument == null ? null : new DocumentReference[]{DocumentReferenceManager.getInstance().create(myDocument)}; - UndoManager.getInstance(myProject).undoableActionPerformed( - new UndoableAction() { - public void undo() { - if (myDocument != null) { - fireTemplateCancelled(); - LookupManager.getInstance(myProject).hideActiveLookup(); - int oldVar = myCurrentVariableNumber; - setCurrentVariableNumber(-1); - currentVariableChanged(oldVar); - } - } - - public void redo() { - //TODO: - // throw new UnexpectedUndoException("Not implemented"); - } - - public DocumentReference[] getAffectedDocuments() { - return refs; - } - - public boolean isGlobal() { - return false; + UndoManager.getInstance(myProject).undoableActionPerformed(new UndoableAction() { + public void undo() { + if (myDocument != null) { + fireTemplateCancelled(); + LookupManager.getInstance(myProject).hideActiveLookup(); + int oldVar = myCurrentVariableNumber; + setCurrentVariableNumber(-1); + currentVariableChanged(oldVar); } } - ); + + public void redo() { + //TODO: + // throw new UnexpectedUndoException("Not implemented"); + } + + public DocumentReference[] getAffectedDocuments() { + return refs; + } + + public boolean isGlobal() { + return false; + } + }); myTemplateIndented = false; myCurrentVariableNumber = -1; mySegments = new TemplateSegments(myEditor); myTemplate = template; + myArgument = argument; if (template.isInline()) { @@ -297,39 +300,37 @@ public class TemplateState implements Disposable { } private void preprocessTemplate(final PsiFile file, int caretOffset, final String textToInsert) { - for(TemplatePreprocessor preprocessor: Extensions.getExtensions(TemplatePreprocessor.EP_NAME)) { + for (TemplatePreprocessor preprocessor : Extensions.getExtensions(TemplatePreprocessor.EP_NAME)) { preprocessor.preprocessTemplate(myEditor, file, caretOffset, textToInsert, myTemplate.getTemplateText()); } } private void processAllExpressions(final TemplateImpl template) { - ApplicationManager.getApplication().runWriteAction( - new Runnable() { - public void run() { - if (!template.isInline()) myDocument.insertString(myTemplateRange.getStartOffset(), template.getTemplateText()); - for (int i = 0; i < template.getSegmentsCount(); i++) { - int segmentOffset = myTemplateRange.getStartOffset() + template.getSegmentOffset(i); - mySegments.addSegment(segmentOffset, segmentOffset); - } + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + if (!template.isInline()) myDocument.insertString(myTemplateRange.getStartOffset(), template.getTemplateText()); + for (int i = 0; i < template.getSegmentsCount(); i++) { + int segmentOffset = myTemplateRange.getStartOffset() + template.getSegmentOffset(i); + mySegments.addSegment(segmentOffset, segmentOffset); + } - calcResults(false); - calcResults(false); //Fixed SCR #[vk500] : all variables should be recalced twice on start. - doReformat(); + calcResults(false); + calcResults(false); //Fixed SCR #[vk500] : all variables should be recalced twice on start. + doReformat(); - int nextVariableNumber = getNextVariableNumber(-1); - if (nextVariableNumber == -1) { - finishTemplateEditing(); - } - else { - setCurrentVariableNumber(nextVariableNumber); - initTabStopHighlighters(); - initListeners(); - focusCurrentExpression(); - currentVariableChanged(-1); - } + int nextVariableNumber = getNextVariableNumber(-1); + if (nextVariableNumber == -1) { + finishTemplateEditing(); + } + else { + setCurrentVariableNumber(nextVariableNumber); + initTabStopHighlighters(); + initListeners(); + focusCurrentExpression(); + currentVariableChanged(-1); } } - ); + }); } private void doReformat() { @@ -352,7 +353,7 @@ public class TemplateState implements Disposable { if (file != null) { IntArrayList indices = initEmptyVariables(); mySegments.setSegmentsGreedy(false); - for(TemplateOptionalProcessor processor: Extensions.getExtensions(TemplateOptionalProcessor.EP_NAME)) { + for (TemplateOptionalProcessor processor : Extensions.getExtensions(TemplateOptionalProcessor.EP_NAME)) { processor.processText(myProject, myTemplate, myDocument, myTemplateRange, myEditor); } mySegments.setSegmentsGreedy(true); @@ -371,7 +372,8 @@ public class TemplateState implements Disposable { setCurrentVariableNumber(-1); currentVariableChanged(oldIndex); fireTemplateCancelled(); - } else { + } + else { calcResults(true); } myDocumentChanged = false; @@ -427,15 +429,16 @@ public class TemplateState implements Disposable { final String s = lookupItems[0].getLookupString(); EditorModificationUtil.insertStringAtCaret(myEditor, s); itemSelected(lookupItems[0], psiFile, currentSegmentNumber, ' ', lookupItems); - } else { + } + else { runLookup(currentSegmentNumber, lookupItems, psiFile); } } else { Result result = expressionNode.calculateResult(context); if (result != null) { - result.handleFocused(psiFile, myDocument, - mySegments.getSegmentStart(currentSegmentNumber), mySegments.getSegmentEnd(currentSegmentNumber)); + result.handleFocused(psiFile, myDocument, mySegments.getSegmentStart(currentSegmentNumber), + mySegments.getSegmentEnd(currentSegmentNumber)); } } focusCurrentHighlighter(true); @@ -465,7 +468,11 @@ public class TemplateState implements Disposable { }); } - private void itemSelected(final LookupElement item, final PsiFile psiFile, final int currentSegmentNumber, final char completionChar, LookupElement[] elements) { + private void itemSelected(final LookupElement item, + final PsiFile psiFile, + final int currentSegmentNumber, + final char completionChar, + LookupElement[] elements) { if (item != null) { PsiDocumentManager.getInstance(myProject).commitAllDocuments(); @@ -490,11 +497,13 @@ public class TemplateState implements Disposable { PsiDocumentManager.getInstance(myProject).commitDocument(myDocument); } - final TemplateLookupSelectionHandler handler = item instanceof LookupItem ? ((LookupItem)item).getAttribute(TemplateLookupSelectionHandler.KEY_IN_LOOKUP_ITEM) : null; + final TemplateLookupSelectionHandler handler = + item instanceof LookupItem ? ((LookupItem)item).getAttribute(TemplateLookupSelectionHandler.KEY_IN_LOOKUP_ITEM) : null; if (handler != null) { - handler.itemSelected(item, psiFile, myDocument, - mySegments.getSegmentStart(currentSegmentNumber), mySegments.getSegmentEnd(currentSegmentNumber)); - } else { + handler.itemSelected(item, psiFile, myDocument, mySegments.getSegmentStart(currentSegmentNumber), + mySegments.getSegmentEnd(currentSegmentNumber)); + } + else { new WriteCommandAction(myProject) { protected void run(com.intellij.openapi.application.Result result) throws Throwable { item.handleInsert(context); @@ -533,45 +542,43 @@ public class TemplateState implements Disposable { } } - ApplicationManager.getApplication().runWriteAction( - new Runnable() { - public void run() { - BitSet calcedSegments = new BitSet(); - int maxAttempts = (myTemplate.getVariableCount()+1)*3; + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + BitSet calcedSegments = new BitSet(); + int maxAttempts = (myTemplate.getVariableCount() + 1) * 3; - do { - maxAttempts--; - calcedSegments.clear(); - for (int i = myCurrentVariableNumber + 1; i < myTemplate.getVariableCount(); i++) { - String variableName = myTemplate.getVariableNameAt(i); - int segmentNumber = myTemplate.getVariableSegmentNumber(variableName); - if (segmentNumber < 0) continue; - Expression expression = myTemplate.getExpressionAt(i); - Expression defaultValue = myTemplate.getDefaultValueAt(i); - String oldValue = getVariableValue(variableName).getText(); - recalcSegment(segmentNumber, isQuick, expression, defaultValue); - final TextResult value = getVariableValue(variableName); - assert value != null : "name=" + variableName + "\ntext=" + myTemplate.getTemplateText(); - String newValue = value.getText(); - if (!newValue.equals(oldValue)) { - calcedSegments.set(segmentNumber); - } + do { + maxAttempts--; + calcedSegments.clear(); + for (int i = myCurrentVariableNumber + 1; i < myTemplate.getVariableCount(); i++) { + String variableName = myTemplate.getVariableNameAt(i); + int segmentNumber = myTemplate.getVariableSegmentNumber(variableName); + if (segmentNumber < 0) continue; + Expression expression = myTemplate.getExpressionAt(i); + Expression defaultValue = myTemplate.getDefaultValueAt(i); + String oldValue = getVariableValue(variableName).getText(); + recalcSegment(segmentNumber, isQuick, expression, defaultValue); + final TextResult value = getVariableValue(variableName); + assert value != null : "name=" + variableName + "\ntext=" + myTemplate.getTemplateText(); + String newValue = value.getText(); + if (!newValue.equals(oldValue)) { + calcedSegments.set(segmentNumber); } + } - for (int i = 0; i < myTemplate.getSegmentsCount(); i++) { - if (!calcedSegments.get(i)) { - String variableName = myTemplate.getSegmentName(i); - String newValue = getVariableValue(variableName).getText(); - int start = mySegments.getSegmentStart(i); - int end = mySegments.getSegmentEnd(i); - replaceString(newValue, start, end, i); - } + for (int i = 0; i < myTemplate.getSegmentsCount(); i++) { + if (!calcedSegments.get(i)) { + String variableName = myTemplate.getSegmentName(i); + String newValue = getVariableValue(variableName).getText(); + int start = mySegments.getSegmentStart(i); + int end = mySegments.getSegmentEnd(i); + replaceString(newValue, start, end, i); } } - while (!calcedSegments.isEmpty() && maxAttempts >= 0); } + while (!calcedSegments.isEmpty() && maxAttempts >= 0); } - ); + }); } private void recalcSegment(int segmentNumber, boolean isQuick, Expression expressionNode, Expression defaultValue) { @@ -615,8 +622,8 @@ public class TemplateState implements Disposable { if (result instanceof RecalculatableResult) { shortenReferences(); PsiDocumentManager.getInstance(myProject).commitDocument(myDocument); - ((RecalculatableResult) result).handleRecalc(psiFile, myDocument, - mySegments.getSegmentStart(segmentNumber), mySegments.getSegmentEnd(segmentNumber)); + ((RecalculatableResult)result) + .handleRecalc(psiFile, myDocument, mySegments.getSegmentStart(segmentNumber), mySegments.getSegmentEnd(segmentNumber)); } } @@ -632,11 +639,9 @@ public class TemplateState implements Disposable { mySegments.setNeighboursGreedy(segmentNumber, true); if (segmentNumberWithTheSameStart != -1) { - mySegments.replaceSegmentAt( - segmentNumberWithTheSameStart, - newEnd, - newEnd + mySegments.getSegmentEnd(segmentNumberWithTheSameStart) - mySegments.getSegmentStart(segmentNumberWithTheSameStart) - ); + mySegments.replaceSegmentAt(segmentNumberWithTheSameStart, newEnd, + newEnd + mySegments.getSegmentEnd(segmentNumberWithTheSameStart) - + mySegments.getSegmentStart(segmentNumberWithTheSameStart)); } } } @@ -723,7 +728,7 @@ public class TemplateState implements Disposable { } public T getProperty(Key key) { - return (T) myProperties.get(key); + return (T)myProperties.get(key); } }; } @@ -743,7 +748,8 @@ public class TemplateState implements Disposable { int offset = -1; if (endSegmentNumber >= 0) { offset = mySegments.getSegmentStart(endSegmentNumber); - } else { + } + else { if (!myTemplate.isSelectionTemplate() && !myTemplate.isInline()) { //do not move caret to the end of range for selection templates offset = myTemplateRange.getEndOffset(); } @@ -758,10 +764,7 @@ public class TemplateState implements Disposable { int selStart = myTemplate.getSelectionStartSegmentNumber(); int selEnd = myTemplate.getSelectionEndSegmentNumber(); if (selStart >= 0 && selEnd >= 0) { - myEditor.getSelectionModel().setSelection( - mySegments.getSegmentStart(selStart), - mySegments.getSegmentStart(selEnd) - ); + myEditor.getSelectionModel().setSelection(mySegments.getSegmentStart(selStart), mySegments.getSegmentStart(selEnd)); } fireBeforeTemplateFinished(); final Editor editor = myEditor; @@ -797,10 +800,12 @@ public class TemplateState implements Disposable { if (expression == null) { return false; } - if (myTemplate.isAlwaysStopAt(currentVariableNumber)) { - return true; - } String variableName = myTemplate.getVariableNameAt(currentVariableNumber); + if (!(TemplateImpl.ARG.equals(variableName) && myArgument != null)) { + if (myTemplate.isAlwaysStopAt(currentVariableNumber)) { + return true; + } + } int segmentNumber = myTemplate.getVariableSegmentNumber(variableName); if (segmentNumber < 0) return false; int start = mySegments.getSegmentStart(segmentNumber); @@ -867,9 +872,7 @@ public class TemplateState implements Disposable { } private RangeHighlighter getSegmentHighlighter(int segmentNumber, boolean isSelected, boolean isEnd) { - TextAttributes attributes = isSelected - ? new TextAttributes(null, null, Color.red, EffectType.BOXED, Font.PLAIN) - : new TextAttributes(); + TextAttributes attributes = isSelected ? new TextAttributes(null, null, Color.red, EffectType.BOXED, Font.PLAIN) : new TextAttributes(); TextAttributes endAttributes = new TextAttributes(); RangeHighlighter segmentHighlighter; @@ -880,8 +883,8 @@ public class TemplateState implements Disposable { .addRangeHighlighter(start, end, HighlighterLayer.LAST + 1, endAttributes, HighlighterTargetArea.EXACT_RANGE); } else { - segmentHighlighter = myEditor.getMarkupModel() - .addRangeHighlighter(start, end, HighlighterLayer.LAST + 1, attributes, HighlighterTargetArea.EXACT_RANGE); + segmentHighlighter = + myEditor.getMarkupModel().addRangeHighlighter(start, end, HighlighterLayer.LAST + 1, attributes, HighlighterTargetArea.EXACT_RANGE); } segmentHighlighter.setGreedyToLeft(true); segmentHighlighter.setGreedyToRight(true); @@ -910,7 +913,7 @@ public class TemplateState implements Disposable { final PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(myDocument); if (file != null) { CodeStyleManager style = CodeStyleManager.getInstance(myProject); - for(TemplateOptionalProcessor optionalProcessor : Extensions.getExtensions(TemplateOptionalProcessor.EP_NAME)) { + for (TemplateOptionalProcessor optionalProcessor : Extensions.getExtensions(TemplateOptionalProcessor.EP_NAME)) { optionalProcessor.processText(myProject, myTemplate, myDocument, myTemplateRange, myEditor); } if (myTemplate.isToReformat()) { @@ -921,7 +924,7 @@ public class TemplateState implements Disposable { if (endSegmentNumber >= 0) { int endVarOffset = mySegments.getSegmentStart(endSegmentNumber); PsiElement marker = style.insertNewLineIndentMarker(file, endVarOffset); - if(marker != null) rangeMarker = myDocument.createRangeMarker(marker.getTextRange()); + if (marker != null) rangeMarker = myDocument.createRangeMarker(marker.getTextRange()); } style.reformatText(file, myTemplateRange.getStartOffset(), myTemplateRange.getEndOffset()); PsiDocumentManager.getInstance(myProject).commitDocument(myDocument); diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java index 88e335594f5b..fe97f81cca29 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java @@ -254,6 +254,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { boolean completed = JobUtil.invokeConcurrentlyUnderMyProgress(new ArrayList(fileSet), new Processor() { public boolean process(final PsiFile file) { if (file instanceof PsiBinaryFile) return true; + file.getViewProvider().getContents(); // load contents outside readaction ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { try { diff --git a/platform/platform-api/src/com/intellij/openapi/progress/Task.java b/platform/platform-api/src/com/intellij/openapi/progress/Task.java index 83f931556f2a..d64ade866bca 100644 --- a/platform/platform-api/src/com/intellij/openapi/progress/Task.java +++ b/platform/platform-api/src/com/intellij/openapi/progress/Task.java @@ -73,7 +73,7 @@ public abstract class Task implements TaskInfo { return myTitle; } - public final Task setTitle(final String title) { + public final Task setTitle(@NotNull String title) { myTitle = title; return this; } diff --git a/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java b/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java index 53789168f005..b37ddc8f06d3 100644 --- a/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java +++ b/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java @@ -347,6 +347,9 @@ public class VfsUtil { if (file == null && uri.contains(JarFileSystem.JAR_SEPARATOR)) { file = JarFileSystem.getInstance().findFileByPath(uri); + if (file == null && base == null) { + file = VirtualFileManager.getInstance().findFileByUrl(uri); + } } if (file == null) { diff --git a/platform/platform-impl/src/com/intellij/ide/actions/WindowAction.java b/platform/platform-impl/src/com/intellij/ide/actions/WindowAction.java new file mode 100644 index 000000000000..688ece5085cf --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/actions/WindowAction.java @@ -0,0 +1,117 @@ +/* + * Copyright 2000-2010 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.ide.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.util.registry.Registry; +import com.intellij.openapi.wm.IdeFrame; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.openapi.wm.ex.WindowManagerEx; + +import javax.swing.*; +import java.awt.*; + +public abstract class WindowAction extends AnAction { + + public static final String NO_WINDOW_ACTIONS = "no.window.actions"; + + protected Window myWindow; + private static JLabel mySizeHelper = new JLabel("W"); + + { + setEnabledInModalContext(true); + } + + @Override + public final void update(AnActionEvent e) { + Window wnd = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow(); + e.getPresentation().setEnabled(wnd != null && !(wnd instanceof IdeFrame)); + + Object noActions = null; + if (wnd instanceof JDialog) { + noActions = ((JDialog)wnd).getRootPane().getClientProperty(NO_WINDOW_ACTIONS); + } else if (wnd instanceof JFrame) { + noActions = ((JFrame)wnd).getRootPane().getClientProperty(NO_WINDOW_ACTIONS); + } + + if (noActions != null && "true".equalsIgnoreCase(noActions.toString())) { + e.getPresentation().setEnabled(false); + } + + if (e.getPresentation().isEnabled()) { + myWindow = wnd; + } else { + myWindow = null; + } + } + + public abstract static class BaseSizeAction extends WindowAction { + + private boolean myHorizontal; + private boolean myPositive; + + protected BaseSizeAction(boolean horizontal, boolean positive) { + myHorizontal = horizontal; + myPositive = positive; + } + + @Override + public void actionPerformed(AnActionEvent e) { + int baseValue = myHorizontal ? mySizeHelper.getPreferredSize().width : mySizeHelper.getPreferredSize().height; + + int inc = baseValue * (myHorizontal ? Registry.intValue("ide.windowSystem.hScrollChars") : Registry.intValue("ide.windowSystem.vScrollChars")); + if (!myPositive) { + inc = -inc; + } + + Rectangle bounds = myWindow.getBounds(); + if (myHorizontal) { + bounds.width += inc; + } else { + bounds.height += inc; + } + + myWindow.setBounds(bounds); + } + } + + public static class IncrementWidth extends BaseSizeAction { + + public IncrementWidth() { + super(true, true); + } + } + + public static class DecrementWidth extends BaseSizeAction { + + public DecrementWidth() { + super(true, false); + } + } + + public static class IncrementHeight extends BaseSizeAction { + public IncrementHeight() { + super(false, true); + } + } + + public static class DecrementHeight extends BaseSizeAction { + public DecrementHeight() { + super(false, false); + } + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapImpl.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapImpl.java index a5205b9b9fd5..bcb93fb5a2b9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapImpl.java @@ -301,6 +301,8 @@ public class KeymapImpl implements Keymap, ExternalizableScheme { } private THashMap> getKeystroke2ListOfIds() { + myKeystroke2ListOfIds = null; + if (myKeystroke2ListOfIds == null) { myKeystroke2ListOfIds = new THashMap>(); fillKeystroke2ListOfIds(myKeystroke2ListOfIds, KeyboardShortcut.class); diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index 930636b43870..fc94ef647fb4 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -708,6 +708,10 @@ action.ResizeToolWindowUp.text=Stretch to Top action.ResizeToolWindowUp.description=Resize active tool window to the top action.ResizeToolWindowDown.text=Stretch to Bottom action.ResizeToolWindowDown.description=Resize active tool window to the bottom +action.IncrementWindowWidth.text=Increment Width +action.DecrementWindowWidth.text=Decrement Width +action.IncrementWindowHeight.text=Increment Height +action.DecrementWindowHeight.text=Decrement Height action.NextTab.text=Select Ne_xt Tab action.NextTab.description=Activate next tab action.PreviousTab.text=Se_lect Previous Tab diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index 4afbe0926e2b..fbed7287a140 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -402,5 +402,10 @@ + + + + + diff --git a/platform/util/src/com/intellij/CommonBundle.java b/platform/util/src/com/intellij/CommonBundle.java index 95e0ed3f95f2..d52f6b91a1bf 100644 --- a/platform/util/src/com/intellij/CommonBundle.java +++ b/platform/util/src/com/intellij/CommonBundle.java @@ -18,6 +18,7 @@ package com.intellij; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.PropertyKey; @@ -51,7 +52,7 @@ public class CommonBundle { return bundle; } - public static String messageOrDefault(@Nullable final ResourceBundle bundle, final String key, final @Nullable String defaultValue, final Object... params) { + public static String messageOrDefault(@Nullable final ResourceBundle bundle, final String key, @Nullable final String defaultValue, final Object... params) { if (bundle == null) return defaultValue; String value; @@ -64,7 +65,7 @@ public class CommonBundle { } else { value = "!" + key + "!"; if (assertKeyIsFound) { - assert false: key + " is not found"; + assert false: key + " is not found in "+BUNDLE; } } } @@ -82,6 +83,7 @@ public class CommonBundle { return messageOrDefault(bundle, key, null, params); } + @NotNull public static String getCancelButtonText() { return message("button.cancel"); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java index a48893061b42..a13d292d1c5f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -39,15 +39,10 @@ import org.jetbrains.plugins.groovy.codeInspection.GroovyImportsTracker; import org.jetbrains.plugins.groovy.config.GroovyConfigUtils; import org.jetbrains.plugins.groovy.highlighter.DefaultHighlighter; import org.jetbrains.plugins.groovy.intentions.utils.DuplicatesUtil; -import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocComment; -import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocMemberReference; -import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocReferenceElement; +import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.*; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; -import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement; -import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; -import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; -import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; +import org.jetbrains.plugins.groovy.lang.psi.*; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList; @@ -86,9 +81,11 @@ import java.util.*; /** * @author ven */ -public class GroovyAnnotator implements Annotator { +public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { private static final Logger LOG = Logger.getInstance("org.jetbrains.plugins.groovy.annotator.GroovyAnnotator"); + private AnnotationHolder myHolder; + private static boolean isDocCommentElement(PsiElement element) { if (element == null) return false; ASTNode node = element.getNode(); @@ -96,87 +93,21 @@ public class GroovyAnnotator implements Annotator { } public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { - if (element instanceof GrCodeReferenceElement) { - checkReferenceElement(holder, (GrCodeReferenceElement)element); + if (element instanceof GroovyPsiElement) { + myHolder = holder; + ((GroovyPsiElement)element).accept(this); + myHolder = null; } - else if (element instanceof GrReferenceExpression) { - checkReferenceExpression(holder, (GrReferenceExpression)element); - } - else if (element instanceof GrTypeDefinition) { - final GrTypeDefinition typeDefinition = (GrTypeDefinition)element; - checkTypeDefinition(holder, typeDefinition); - checkTypeDefinitionModifiers(holder, typeDefinition); - final GrTypeDefinitionBody body = typeDefinition.getBody(); - if (body != null) checkDuplicateMethod(body.getGroovyMethods(), holder); - checkImplementedMethodsOfClass(holder, typeDefinition); - } - else if (element instanceof GrMethod) { - final GrMethod method = (GrMethod)element; - checkMethodDefinitionModifiers(holder, method); - checkInnerMethod(holder, method); - } - else if (element instanceof GrVariableDeclaration) { - checkVariableDeclaration(holder, (GrVariableDeclaration)element); - } - else if (element instanceof GrVariable) { - if (element instanceof GrMember) { - highlightMember(holder, ((GrMember)element)); - checkStaticDeclarationsInInnerClass((GrMember)element, holder); - } - checkVariable(holder, (GrVariable)element); - } - else if (element instanceof GrAssignmentExpression) { - checkAssignmentExpression((GrAssignmentExpression)element, holder); - } - else if (element instanceof GrReturnStatement) { - checkReturnStatement((GrReturnStatement)element, holder); - } - else if (element instanceof GrListOrMap) { - checkMap(((GrListOrMap)element).getNamedArguments(), holder); - } - else if (element instanceof GrNewExpression) { - checkNewExpression(holder, (GrNewExpression)element); - } - else if (element instanceof GrDocMemberReference) { - checkGrDocMemberReference((GrDocMemberReference)element, holder); - } - else if (element instanceof GrConstructorInvocation) { - checkConstructorInvocation(holder, (GrConstructorInvocation)element); - } - else if (element instanceof GrFlowInterruptingStatement) { - checkFlowInterruptStatement(((GrFlowInterruptingStatement)element), holder); - } else if (element instanceof GrLabeledStatement) { - checkLabeledStatement(((GrLabeledStatement) element), holder); - } - else if (element.getParent() instanceof GrDocReferenceElement) { - checkGrDocReferenceElement(holder, element); - } - else if (element instanceof GrPackageDefinition) { - //todo: if reference isn't resolved it construct package definition - checkPackageReference(holder, (GrPackageDefinition)element); - } - else if (element instanceof GrThisReferenceExpression || element instanceof GrSuperReferenceExpression) { - checkThisOrSuperReferenceExpression(((GrExpression)element), holder); - } - else if (element instanceof GrLiteral) { - checkLiteral(((GrLiteral)element), holder); - } - else if (element instanceof GrForInClause) { - checkForInClause(((GrForInClause)element), holder); - } - else if (element instanceof GroovyFile) { - final GroovyFile file = (GroovyFile)element; - if (file.isScript()) { - checkScriptDuplicateMethod(file.getTopLevelDefinitions(), holder); - } - } - else if (element instanceof GrImportStatement) { - checkAnnotationList(holder, ((GrImportStatement)element).getAnnotationList(), GroovyBundle.message("import.statement.cannot.have.modifiers")); + } + + @Override + public void visitElement(GroovyPsiElement element) { + if (element.getParent() instanceof GrDocReferenceElement) { + checkGrDocReferenceElement(myHolder, element); } else { final ASTNode node = element.getNode(); - if (node != null && - !(element instanceof PsiWhiteSpace) && + if (!(element instanceof PsiWhiteSpace) && !GroovyTokenTypes.COMMENT_SET.contains(node.getElementType()) && element.getContainingFile() instanceof GroovyFile && !isDocCommentElement(element)) { @@ -185,7 +116,377 @@ public class GroovyAnnotator implements Annotator { } } - private static void checkForInClause(GrForInClause forInClause, AnnotationHolder holder) { + @Override + public void visitCodeReferenceElement(GrCodeReferenceElement refElement) { + final PsiElement parent = refElement.getParent(); + GroovyResolveResult resolveResult = refElement.advancedResolve(); + highlightAnnotation(myHolder, refElement, resolveResult); + registerUsedImport(refElement, resolveResult); + highlightAnnotation(myHolder, refElement, resolveResult); + if (refElement.getReferenceName() != null) { + + if (parent instanceof GrImportStatement && ((GrImportStatement)parent).isStatic() && refElement.multiResolve(false).length > 0) { + return; + } + + checkSingleResolvedElement(myHolder, refElement, resolveResult); + } + + } + + @Override + public void visitReferenceExpression(GrReferenceExpression referenceExpression) { + GroovyResolveResult resolveResult = referenceExpression.advancedResolve(); + GroovyResolveResult[] results = referenceExpression.multiResolve(false); //cached + for (GroovyResolveResult result : results) { + registerUsedImport(referenceExpression, result); + } + + PsiElement resolved = resolveResult.getElement(); + final PsiElement parent = referenceExpression.getParent(); + if (resolved != null) { + if (resolved instanceof PsiMember) { + highlightMemberResolved(myHolder, referenceExpression, ((PsiMember)resolved)); + } + if (!resolveResult.isAccessible()) { + String message = GroovyBundle.message("cannot.access", referenceExpression.getReferenceName()); + myHolder.createWarningAnnotation(referenceExpression.getReferenceNameElement(), message); + } + if (!resolveResult.isStaticsOK() && resolved instanceof PsiModifierListOwner) { + if (!((PsiModifierListOwner)resolved).hasModifierProperty(PsiModifier.STATIC)) { + myHolder.createWarningAnnotation(referenceExpression, GroovyBundle.message("cannot.reference.nonstatic", referenceExpression.getReferenceName())); + } + } + } + else { + GrExpression qualifier = referenceExpression.getQualifierExpression(); + if (qualifier == null && isDeclarationAssignment(referenceExpression)) return; + + if (parent instanceof GrReferenceExpression && "class".equals(((GrReferenceExpression)parent).getReferenceName())) { + checkSingleResolvedElement(myHolder, referenceExpression, resolveResult); + } + } + + if (parent instanceof GrCall) { + if (resolved == null && results.length > 0) { + resolved = results[0].getElement(); + resolveResult = results[0]; + } + if (resolved instanceof PsiMethod && resolved.getUserData(GrMethod.BUILDER_METHOD) == null) { + checkMethodApplicability(resolveResult, referenceExpression, myHolder); + } + else { + checkClosureApplicability(resolveResult, referenceExpression.getType(), referenceExpression, myHolder); + } + } + if (isDeclarationAssignment(referenceExpression) || resolved instanceof PsiPackage) return; + + if (resolved == null) { + PsiElement refNameElement = referenceExpression.getReferenceNameElement(); + PsiElement elt = refNameElement == null ? referenceExpression : refNameElement; + Annotation annotation = myHolder.createInfoAnnotation(elt, null); + final GrExpression qualifier = referenceExpression.getQualifierExpression(); + if (qualifier == null) { + if (!(parent instanceof GrCall)) { + registerCreateClassByTypeFix(referenceExpression, annotation); + registerAddImportFixes(referenceExpression, annotation); + } + } else { + if (qualifier.getType() == null) { + return; + } + } + registerReferenceFixes(referenceExpression, annotation); + annotation.setTextAttributes(DefaultHighlighter.UNRESOLVED_ACCESS); + } + } + + @Override + public void visitTypeDefinition(GrTypeDefinition typeDefinition) { + checkTypeDefinition(myHolder, typeDefinition); + checkTypeDefinitionModifiers(myHolder, typeDefinition); + + final GrTypeDefinitionBody body = typeDefinition.getBody(); + if (body != null) checkDuplicateMethod(body.getGroovyMethods(), myHolder); + checkImplementedMethodsOfClass(myHolder, typeDefinition); + } + + @Override + public void visitMethod(GrMethod method) { + checkMethodDefinitionModifiers(myHolder, method); + checkInnerMethod(myHolder, method); + } + + @Override + public void visitVariableDeclaration(GrVariableDeclaration variableDeclaration) { + + PsiElement parent = variableDeclaration.getParent(); + assert parent != null; + + PsiElement typeDef = parent.getParent(); + if (typeDef != null && typeDef instanceof GrTypeDefinition) { + PsiModifierList modifiersList = variableDeclaration.getModifierList(); + checkAccessModifiers(myHolder, modifiersList); + + if (modifiersList.hasExplicitModifier(PsiModifier.VOLATILE) && modifiersList.hasExplicitModifier(PsiModifier.FINAL)) { + myHolder.createErrorAnnotation(modifiersList, GroovyBundle.message("illegal.combination.of.modifiers.volatile.and.final")); + } + + if (modifiersList.hasExplicitModifier(PsiModifier.NATIVE)) { + myHolder.createErrorAnnotation(modifiersList, GroovyBundle.message("variable.cannot.be.native")); + } + + if (modifiersList.hasExplicitModifier(PsiModifier.ABSTRACT)) { + myHolder.createErrorAnnotation(modifiersList, GroovyBundle.message("variable.cannot.be.abstract")); + } + } + } + + @Override + public void visitVariable(GrVariable variable) { + if (variable instanceof GrMember) { + highlightMember(myHolder, ((GrMember)variable)); + checkStaticDeclarationsInInnerClass((GrMember)variable, myHolder); + } + PropertyResolverProcessor processor = new DuplicateVariablesProcessor(variable); + final GroovyPsiElement duplicate = + ResolveUtil.resolveExistingElement(variable, processor, GrVariable.class, GrReferenceExpression.class); + + if (duplicate instanceof GrVariable) { + if (duplicate instanceof GrField && !(variable instanceof GrField)) { + myHolder + .createWarningAnnotation(variable.getNameIdentifierGroovy(), GroovyBundle.message("field.already.defined", variable.getName())); + } + else { + final String key = duplicate instanceof GrField ? "field.already.defined" : "variable.already.defined"; + myHolder.createErrorAnnotation(variable.getNameIdentifierGroovy(), GroovyBundle.message(key, variable.getName())); + } + } + } + + @Override + public void visitAssignmentExpression(GrAssignmentExpression expression) { + GrExpression lValue = expression.getLValue(); + if (!PsiUtil.mightBeLVlaue(lValue)) { + myHolder.createErrorAnnotation(lValue, GroovyBundle.message("invalid.lvalue")); + } + } + + @Override + public void visitReturnStatement(GrReturnStatement returnStatement) { + final GrExpression value = returnStatement.getReturnValue(); + if (value != null) { + final PsiType type = value.getType(); + if (type != null) { + final GrParametersOwner owner = PsiTreeUtil.getParentOfType(returnStatement, GrMethod.class, GrClosableBlock.class); + if (owner instanceof PsiMethod) { + final PsiMethod method = (PsiMethod)owner; + if (method.isConstructor()) { + myHolder.createErrorAnnotation(value, GroovyBundle.message("cannot.return.from.constructor")); + } + else { + final PsiType methodType = method.getReturnType(); + if (methodType != null) { + if (PsiType.VOID.equals(methodType)) { + myHolder.createErrorAnnotation(value, GroovyBundle.message("cannot.return.from.void.method")); + } + } + } + } + } + } + } + + @Override + public void visitListOrMap(GrListOrMap listOrMap) { + final Map> map = DuplicatesUtil.factorDuplicates(listOrMap.getNamedArguments(), new TObjectHashingStrategy() { + public int computeHashCode(GrNamedArgument arg) { + final GrArgumentLabel label = arg.getLabel(); + if (label == null) return 0; + final String name = label.getName(); + if (name == null) return 0; + return name.hashCode(); + } + + public boolean equals(GrNamedArgument arg1, GrNamedArgument arg2) { + final GrArgumentLabel label1 = arg1.getLabel(); + final GrArgumentLabel label2 = arg2.getLabel(); + if (label1 == null || label2 == null) { + return label1 == null && label2 == null; + } + final String name1 = label1.getName(); + final String name2 = label2.getName(); + if (name1 == null || name2 == null) { + return name1 == null && name2 == null; + } + return name1.equals(name2); + } + }); + + processDuplicates(map, myHolder); + } + + @Override + public void visitNewExpression(GrNewExpression newExpression) { + if (newExpression.getArrayCount() > 0) return; + GrCodeReferenceElement refElement = newExpression.getReferenceElement(); + if (refElement == null) return; + final PsiElement element = refElement.resolve(); + if (element instanceof PsiClass) { + PsiClass clazz = (PsiClass)element; + if (clazz.hasModifierProperty(PsiModifier.ABSTRACT)) { + if (newExpression.getAnonymousClassDefinition() == null) { + String message = clazz.isInterface() + ? GroovyBundle.message("cannot.instantiate.interface", clazz.getName()) + : GroovyBundle.message("cannot.instantiate.abstract.class", clazz.getName()); + myHolder.createErrorAnnotation(refElement, message); + } + return; + } + if (newExpression.getQualifier() != null) { + if (clazz.hasModifierProperty(PsiModifier.STATIC)) { + myHolder.createErrorAnnotation(newExpression, GroovyBundle.message("qualified.new.of.static.class")); + } + } else { + final PsiClass outerClass = clazz.getContainingClass(); + if (com.intellij.psi.util.PsiUtil.isInnerClass(clazz) && !PsiUtil.hasEnclosingInstanceInScope(outerClass, newExpression, true)) { + myHolder.createErrorAnnotation(newExpression, GroovyBundle.message("cannot.reference.nonstatic", clazz.getQualifiedName())); + } + } + } + + final GroovyResolveResult constructorResolveResult = newExpression.resolveConstructorGenerics(); + if (constructorResolveResult.getElement() != null) { + checkMethodApplicability(constructorResolveResult, refElement, myHolder); + final GrArgumentList argList = newExpression.getArgumentList(); + if (argList != null && argList.getExpressionArguments().length == 0) checkDefaultMapConstructor(myHolder, argList); + } + else { + final GroovyResolveResult[] results = newExpression.multiResolveConstructor(); + final GrArgumentList argList = newExpression.getArgumentList(); + PsiElement toHighlight = argList != null ? argList : refElement.getReferenceNameElement(); + + if (results.length > 0) { + String message = GroovyBundle.message("ambiguous.constructor.call"); + myHolder.createWarningAnnotation(toHighlight, message); + } + else { + if (element instanceof PsiClass) { + //default constructor invocation + PsiType[] argumentTypes = PsiUtil.getArgumentTypes(refElement, true, true); + if (argumentTypes != null && argumentTypes.length > 0) { + String message = GroovyBundle.message("cannot.find.default.constructor", ((PsiClass)element).getName()); + myHolder.createWarningAnnotation(toHighlight, message); + } + else checkDefaultMapConstructor(myHolder, argList); + } + } + } + } + + @Override + public void visitDocMethodReference(GrDocMethodReference reference) { + checkGrDocMemberReference(reference, myHolder); + } + + @Override + public void visitDocFieldReference(GrDocFieldReference reference) { + checkGrDocMemberReference(reference, myHolder); + } + + @Override + public void visitConstructorInvocation(GrConstructorInvocation invocation) { + final GroovyResolveResult resolveResult = invocation.resolveConstructorGenerics(); + if (resolveResult != null) { + checkMethodApplicability(resolveResult, invocation.getThisOrSuperKeyword(), myHolder); + } + else { + final GroovyResolveResult[] results = invocation.multiResolveConstructor(); + final GrArgumentList argList = invocation.getArgumentList(); + if (results.length > 0) { + String message = GroovyBundle.message("ambiguous.constructor.call"); + myHolder.createWarningAnnotation(argList, message); + } + else { + final PsiClass clazz = invocation.getDelegatedClass(); + if (clazz != null) { + //default constructor invocation + PsiType[] argumentTypes = PsiUtil.getArgumentTypes(invocation.getThisOrSuperKeyword(), true, true); + if (argumentTypes != null && argumentTypes.length > 0) { + String message = GroovyBundle.message("cannot.find.default.constructor", clazz.getName()); + myHolder.createWarningAnnotation(argList, message); + } + } + } + } + } + + @Override + public void visitBreakStatement(GrBreakStatement breakStatement) { + checkFlowInterruptStatement(breakStatement, myHolder); + } + + @Override + public void visitContinueStatement(GrContinueStatement continueStatement) { + checkFlowInterruptStatement(continueStatement, myHolder); + } + + @Override + public void visitLabeledStatement(GrLabeledStatement labeledStatement) { + final String name = labeledStatement.getLabelName(); + if (ResolveUtil.resolveLabeledStatement(name, labeledStatement, true) != null) { + myHolder.createWarningAnnotation(labeledStatement.getLabel(), GroovyBundle.message("label.already.used", name)); + } + } + + @Override + public void visitPackageDefinition(GrPackageDefinition packageDefinition) { + //todo: if reference isn't resolved it construct package definition + final PsiFile file = packageDefinition.getContainingFile(); + assert file != null; + + PsiDirectory psiDirectory = file.getContainingDirectory(); + if (psiDirectory != null) { + PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(psiDirectory); + if (aPackage != null) { + String packageName = aPackage.getQualifiedName(); + if (!packageDefinition.getPackageName().equals(packageName)) { + final Annotation annotation = myHolder.createWarningAnnotation(packageDefinition, "wrong package name"); + annotation.registerFix(new ChangePackageQuickFix((GroovyFile)packageDefinition.getContainingFile(), packageName)); + } + } + } + final GrModifierList modifierList = packageDefinition.getAnnotationList(); + checkAnnotationList(myHolder, modifierList, GroovyBundle.message("package.definition.cannot.have.modifiers")); + } + + @Override + public void visitSuperExpression(GrSuperReferenceExpression superExpression) { + checkThisOrSuperReferenceExpression(superExpression, myHolder); + } + + @Override + public void visitThisExpression(GrThisReferenceExpression thisExpression) { + checkThisOrSuperReferenceExpression(thisExpression, myHolder); + } + + @Override + public void visitLiteralExpression(GrLiteral literal) { + String text = literal.getText(); + if (text.startsWith("'''")) { + if (text.length() < 6 || !text.endsWith("'''")) { + myHolder.createErrorAnnotation(literal, GroovyBundle.message("string.end.expected")); + } + } + else if (text.startsWith("'")) { + if (text.length() < 2 || !text.endsWith("'")) { + myHolder.createErrorAnnotation(literal, GroovyBundle.message("string.end.expected")); + } + } + } + + @Override + public void visitForInClause(GrForInClause forInClause) { final GrVariable[] declaredVariables = forInClause.getDeclaredVariables(); if (declaredVariables.length < 1) return; final GrVariable variable = declaredVariables[0]; @@ -197,29 +498,28 @@ public class GroovyAnnotator implements Annotator { final String modifierText = modifier.getText(); if (PsiModifier.FINAL.equals(modifierText)) continue; if ("def".equals(modifierText)) continue; - holder.createErrorAnnotation(modifier, GroovyBundle.message("not.allowed.modifier.in.forin", modifierText)); + myHolder.createErrorAnnotation(modifier, GroovyBundle.message("not.allowed.modifier.in.forin", modifierText)); } } - private static void checkLiteral(GrLiteral literal, AnnotationHolder holder) { - String text = literal.getText(); - if (text.startsWith("'''")) { - if (text.length() < 6 || !text.endsWith("'''")) { - holder.createErrorAnnotation(literal, GroovyBundle.message("string.end.expected")); - } - } - else if (text.startsWith("'")) { - if (text.length() < 2 || !text.endsWith("'")) { - holder.createErrorAnnotation(literal, GroovyBundle.message("string.end.expected")); + @Override + public void visitFile(GroovyFileBase file) { + if (!file.isScript()) return; + + List methods = new ArrayList(); + + for (GrTopLevelDefintion topLevelDefinition : file.getTopLevelDefinitions()) { + if (topLevelDefinition instanceof GrMethod) { + methods.add(((GrMethod)topLevelDefinition)); } } + + checkDuplicateMethod(methods.toArray(new GrMethod[methods.size()]), myHolder); } - private static void checkLabeledStatement(GrLabeledStatement statement, AnnotationHolder holder) { - final String name = statement.getLabelName(); - if (ResolveUtil.resolveLabeledStatement(name, statement, true) != null) { - holder.createWarningAnnotation(statement.getLabel(), GroovyBundle.message("label.already.used", name)); - } + @Override + public void visitImportStatement(GrImportStatement importStatement) { + checkAnnotationList(myHolder, importStatement.getAnnotationList(), GroovyBundle.message("import.statement.cannot.have.modifiers")); } private static void checkFlowInterruptStatement(GrFlowInterruptingStatement statement, AnnotationHolder holder) { @@ -314,25 +614,6 @@ public class GroovyAnnotator implements Annotator { } } - private static void checkPackageReference(AnnotationHolder holder, GrPackageDefinition packageDefinition) { - final PsiFile file = packageDefinition.getContainingFile(); - assert file != null; - - PsiDirectory psiDirectory = file.getContainingDirectory(); - if (psiDirectory != null) { - PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(psiDirectory); - if (aPackage != null) { - String packageName = aPackage.getQualifiedName(); - if (!packageDefinition.getPackageName().equals(packageName)) { - final Annotation annotation = holder.createWarningAnnotation(packageDefinition, "wrong package name"); - annotation.registerFix(new ChangePackageQuickFix((GroovyFile)packageDefinition.getContainingFile(), packageName)); - } - } - } - final GrModifierList modifierList = packageDefinition.getAnnotationList(); - checkAnnotationList(holder, modifierList, GroovyBundle.message("package.definition.cannot.have.modifiers")); - } - private static void checkAnnotationList(AnnotationHolder holder, @Nullable GrModifierList modifierList, String message) { if (modifierList == null) return; final PsiElement[] modifiers = modifierList.getModifiers(); @@ -366,32 +647,6 @@ public class GroovyAnnotator implements Annotator { annotation.registerFix(new ImplementMethodsQuickFix(typeDefinition)); } - private static void checkConstructorInvocation(AnnotationHolder holder, GrConstructorInvocation invocation) { - final GroovyResolveResult resolveResult = invocation.resolveConstructorGenerics(); - if (resolveResult != null) { - checkMethodApplicability(resolveResult, invocation.getThisOrSuperKeyword(), holder); - } - else { - final GroovyResolveResult[] results = invocation.multiResolveConstructor(); - final GrArgumentList argList = invocation.getArgumentList(); - if (results.length > 0) { - String message = GroovyBundle.message("ambiguous.constructor.call"); - holder.createWarningAnnotation(argList, message); - } - else { - final PsiClass clazz = invocation.getDelegatedClass(); - if (clazz != null) { - //default constructor invocation - PsiType[] argumentTypes = PsiUtil.getArgumentTypes(invocation.getThisOrSuperKeyword(), true, true); - if (argumentTypes != null && argumentTypes.length > 0) { - String message = GroovyBundle.message("cannot.find.default.constructor", clazz.getName()); - holder.createWarningAnnotation(argList, message); - } - } - } - } - } - private static void checkInnerMethod(AnnotationHolder holder, GrMethod grMethod) { final PsiElement parent = grMethod.getParent(); if (parent instanceof GrOpenBlock || parent instanceof GrClosableBlock) { @@ -399,34 +654,6 @@ public class GroovyAnnotator implements Annotator { } } - private static void checkMap(GrNamedArgument[] namedArguments, AnnotationHolder holder) { - final Map> map = DuplicatesUtil.factorDuplicates(namedArguments, new TObjectHashingStrategy() { - public int computeHashCode(GrNamedArgument arg) { - final GrArgumentLabel label = arg.getLabel(); - if (label == null) return 0; - final String name = label.getName(); - if (name == null) return 0; - return name.hashCode(); - } - - public boolean equals(GrNamedArgument arg1, GrNamedArgument arg2) { - final GrArgumentLabel label1 = arg1.getLabel(); - final GrArgumentLabel label2 = arg2.getLabel(); - if (label1 == null || label2 == null) { - return label1 == null && label2 == null; - } - final String name1 = label1.getName(); - final String name2 = label2.getName(); - if (name1 == null || name2 == null) { - return name1 == null && name2 == null; - } - return name1.equals(name2); - } - }); - - processDuplicates(map, holder); - } - protected static void processDuplicates(Map> map, AnnotationHolder holder) { for (List args : map.values()) { for (int i = 1; i < args.size(); i++) { @@ -436,30 +663,6 @@ public class GroovyAnnotator implements Annotator { } } - private static void checkVariableDeclaration(AnnotationHolder holder, GrVariableDeclaration variableDeclaration) { - - PsiElement parent = variableDeclaration.getParent(); - assert parent != null; - - PsiElement typeDef = parent.getParent(); - if (typeDef != null && typeDef instanceof GrTypeDefinition) { - PsiModifierList modifiersList = variableDeclaration.getModifierList(); - checkAccessModifiers(holder, modifiersList); - - if (modifiersList.hasExplicitModifier(PsiModifier.VOLATILE) && modifiersList.hasExplicitModifier(PsiModifier.FINAL)) { - holder.createErrorAnnotation(modifiersList, GroovyBundle.message("illegal.combination.of.modifiers.volatile.and.final")); - } - - if (modifiersList.hasExplicitModifier(PsiModifier.NATIVE)) { - holder.createErrorAnnotation(modifiersList, GroovyBundle.message("variable.cannot.be.native")); - } - - if (modifiersList.hasExplicitModifier(PsiModifier.ABSTRACT)) { - holder.createErrorAnnotation(modifiersList, GroovyBundle.message("variable.cannot.be.abstract")); - } - } - } - private static void checkMethodDefinitionModifiers(AnnotationHolder holder, GrMethod method) { final PsiModifierList modifiersList = method.getModifierList(); checkAccessModifiers(holder, modifiersList); @@ -597,18 +800,6 @@ public class GroovyAnnotator implements Annotator { } } - private static void checkScriptDuplicateMethod(GrTopLevelDefintion[] topLevelDefinitions, AnnotationHolder holder) { - List methods = new ArrayList(); - - for (GrTopLevelDefintion topLevelDefinition : topLevelDefinitions) { - if (topLevelDefinition instanceof GrMethod) { - methods.add(((GrMethod)topLevelDefinition)); - } - } - - checkDuplicateMethod(methods.toArray(new GrMethod[methods.size()]), holder); - } - private static void checkDuplicateMethod(GrMethod[] methods, AnnotationHolder holder) { final Map> map = DuplicatesUtil.factorDuplicates(methods, new TObjectHashingStrategy() { public int computeHashCode(GrMethod method) { @@ -639,51 +830,6 @@ public class GroovyAnnotator implements Annotator { } - private static void checkReturnStatement(GrReturnStatement returnStatement, AnnotationHolder holder) { - final GrExpression value = returnStatement.getReturnValue(); - if (value != null) { - final PsiType type = value.getType(); - if (type != null) { - final GrParametersOwner owner = PsiTreeUtil.getParentOfType(returnStatement, GrMethod.class, GrClosableBlock.class); - if (owner instanceof PsiMethod) { - final PsiMethod method = (PsiMethod)owner; - if (method.isConstructor()) { - holder.createErrorAnnotation(value, GroovyBundle.message("cannot.return.from.constructor")); - } - else { - final PsiType methodType = method.getReturnType(); - if (methodType != null) { - if (PsiType.VOID.equals(methodType)) { - holder.createErrorAnnotation(value, GroovyBundle.message("cannot.return.from.void.method")); - } - } - } - } - } - } - } - - private static void checkAssignmentExpression(GrAssignmentExpression assignment, AnnotationHolder holder) { - GrExpression lValue = assignment.getLValue(); - if (!PsiUtil.mightBeLVlaue(lValue)) { - holder.createErrorAnnotation(lValue, GroovyBundle.message("invalid.lvalue")); - } - } - - private static void checkVariable(AnnotationHolder holder, GrVariable variable) { - PropertyResolverProcessor processor = new DuplicateVariablesProcessor(variable); - final GroovyPsiElement duplicate = ResolveUtil.resolveExistingElement(variable, processor, GrVariable.class, GrReferenceExpression.class); - - if (duplicate instanceof GrVariable) { - if (duplicate instanceof GrField && !(variable instanceof GrField)) { - holder.createWarningAnnotation(variable.getNameIdentifierGroovy(), GroovyBundle.message("field.already.defined", variable.getName())); - } else { - final String key = duplicate instanceof GrField ? "field.already.defined" : "variable.already.defined"; - holder.createErrorAnnotation(variable.getNameIdentifierGroovy(), GroovyBundle.message(key, variable.getName())); - } - } - } - private static void checkTypeDefinition(AnnotationHolder holder, GrTypeDefinition typeDefinition) { final GroovyConfigUtils configUtils = GroovyConfigUtils.getInstance(); if (typeDefinition.isAnnotationType()) { @@ -804,72 +950,6 @@ public class GroovyAnnotator implements Annotator { } } - private static void checkReferenceExpression(AnnotationHolder holder, final GrReferenceExpression refExpr) { - GroovyResolveResult resolveResult = refExpr.advancedResolve(); - GroovyResolveResult[] results = refExpr.multiResolve(false); //cached - for (GroovyResolveResult result : results) { - registerUsedImport(refExpr, result); - } - - PsiElement resolved = resolveResult.getElement(); - final PsiElement parent = refExpr.getParent(); - if (resolved != null) { - if (resolved instanceof PsiMember) { - highlightMemberResolved(holder, refExpr, ((PsiMember)resolved)); - } - if (!resolveResult.isAccessible()) { - String message = GroovyBundle.message("cannot.access", refExpr.getReferenceName()); - holder.createWarningAnnotation(refExpr.getReferenceNameElement(), message); - } - if (!resolveResult.isStaticsOK() && resolved instanceof PsiModifierListOwner) { - if (!((PsiModifierListOwner)resolved).hasModifierProperty(PsiModifier.STATIC)) { - holder.createWarningAnnotation(refExpr, GroovyBundle.message("cannot.reference.nonstatic", refExpr.getReferenceName())); - } - } - } - else { - GrExpression qualifier = refExpr.getQualifierExpression(); - if (qualifier == null && isDeclarationAssignment(refExpr)) return; - - if (parent instanceof GrReferenceExpression && "class".equals(((GrReferenceExpression)parent).getReferenceName())) { - checkSingleResolvedElement(holder, refExpr, resolveResult); - } - } - - if (parent instanceof GrCall) { - if (resolved == null && results.length > 0) { - resolved = results[0].getElement(); - resolveResult = results[0]; - } - if (resolved instanceof PsiMethod && resolved.getUserData(GrMethod.BUILDER_METHOD) == null) { - checkMethodApplicability(resolveResult, refExpr, holder); - } - else { - checkClosureApplicability(resolveResult, refExpr.getType(), refExpr, holder); - } - } - if (isDeclarationAssignment(refExpr) || resolved instanceof PsiPackage) return; - - if (resolved == null) { - PsiElement refNameElement = refExpr.getReferenceNameElement(); - PsiElement elt = refNameElement == null ? refExpr : refNameElement; - Annotation annotation = holder.createInfoAnnotation(elt, null); - final GrExpression qualifier = refExpr.getQualifierExpression(); - if (qualifier == null) { - if (!(parent instanceof GrCall)) { - registerCreateClassByTypeFix(refExpr, annotation); - registerAddImportFixes(refExpr, annotation); - } - } else { - if (qualifier.getType() == null) { - return; - } - } - registerReferenceFixes(refExpr, annotation); - annotation.setTextAttributes(DefaultHighlighter.UNRESOLVED_ACCESS); - } - } - private static void registerReferenceFixes(GrReferenceExpression refExpr, Annotation annotation) { PsiClass targetClass = QuickfixUtil.findTargetClass(refExpr); if (targetClass == null) return; @@ -994,23 +1074,6 @@ public class GroovyAnnotator implements Annotator { return false; } - private static void checkReferenceElement(AnnotationHolder holder, final GrCodeReferenceElement refElement) { - final PsiElement parent = refElement.getParent(); - GroovyResolveResult resolveResult = refElement.advancedResolve(); - highlightAnnotation(holder, refElement, resolveResult); - registerUsedImport(refElement, resolveResult); - highlightAnnotation(holder, refElement, resolveResult); - if (refElement.getReferenceName() != null) { - - if (parent instanceof GrImportStatement && ((GrImportStatement)parent).isStatic() && refElement.multiResolve(false).length > 0) { - return; - } - - checkSingleResolvedElement(holder, refElement, resolveResult); - } - - } - private static void checkSingleResolvedElement(AnnotationHolder holder, GrReferenceElement refElement, GroovyResolveResult resolveResult) { final PsiElement resolved = resolveResult.getElement(); if (resolved == null) { @@ -1033,63 +1096,6 @@ public class GroovyAnnotator implements Annotator { } } - private static void checkNewExpression(AnnotationHolder holder, GrNewExpression newExpression) { - if (newExpression.getArrayCount() > 0) return; - GrCodeReferenceElement refElement = newExpression.getReferenceElement(); - if (refElement == null) return; - final PsiElement element = refElement.resolve(); - if (element instanceof PsiClass) { - PsiClass clazz = (PsiClass)element; - if (clazz.hasModifierProperty(PsiModifier.ABSTRACT)) { - if (newExpression.getAnonymousClassDefinition() == null) { - String message = clazz.isInterface() - ? GroovyBundle.message("cannot.instantiate.interface", clazz.getName()) - : GroovyBundle.message("cannot.instantiate.abstract.class", clazz.getName()); - holder.createErrorAnnotation(refElement, message); - } - return; - } - if (newExpression.getQualifier() != null) { - if (clazz.hasModifierProperty(PsiModifier.STATIC)) { - holder.createErrorAnnotation(newExpression, GroovyBundle.message("qualified.new.of.static.class")); - } - } else { - final PsiClass outerClass = clazz.getContainingClass(); - if (com.intellij.psi.util.PsiUtil.isInnerClass(clazz) && !PsiUtil.hasEnclosingInstanceInScope(outerClass, newExpression, true)) { - holder.createErrorAnnotation(newExpression, GroovyBundle.message("cannot.reference.nonstatic", clazz.getQualifiedName())); - } - } - } - - final GroovyResolveResult constructorResolveResult = newExpression.resolveConstructorGenerics(); - if (constructorResolveResult.getElement() != null) { - checkMethodApplicability(constructorResolveResult, refElement, holder); - final GrArgumentList argList = newExpression.getArgumentList(); - if (argList != null && argList.getExpressionArguments().length == 0) checkDefaultMapConstructor(holder, argList); - } - else { - final GroovyResolveResult[] results = newExpression.multiResolveConstructor(); - final GrArgumentList argList = newExpression.getArgumentList(); - PsiElement toHighlight = argList != null ? argList : refElement.getReferenceNameElement(); - - if (results.length > 0) { - String message = GroovyBundle.message("ambiguous.constructor.call"); - holder.createWarningAnnotation(toHighlight, message); - } - else { - if (element instanceof PsiClass) { - //default constructor invocation - PsiType[] argumentTypes = PsiUtil.getArgumentTypes(refElement, true, true); - if (argumentTypes != null && argumentTypes.length > 0) { - String message = GroovyBundle.message("cannot.find.default.constructor", ((PsiClass)element).getName()); - holder.createWarningAnnotation(toHighlight, message); - } - else checkDefaultMapConstructor(holder, argList); - } - } - } - } - private static void checkDefaultMapConstructor(AnnotationHolder holder, GrArgumentList argList) { if (argList != null) { final GrNamedArgument[] args = argList.getNamedArguments(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java index d0374672fd58..e0ab7650578e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java @@ -17,7 +17,10 @@ package org.jetbrains.plugins.groovy.compiler.generator; import com.intellij.compiler.CompilerConfiguration; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.compiler.*; +import com.intellij.openapi.compiler.CompileContext; +import com.intellij.openapi.compiler.CompilerManager; +import com.intellij.openapi.compiler.TimestampValidityState; +import com.intellij.openapi.compiler.ValidityState; import com.intellij.openapi.compiler.options.ExcludedEntriesConfiguration; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.JavaModuleType; @@ -36,6 +39,7 @@ import com.intellij.util.ArrayUtil; import com.intellij.util.containers.HashSet; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.compiler.GroovyCompilerConfiguration; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; @@ -68,8 +72,7 @@ import java.util.*; * @author: Dmitry.Krasilschikov * @date: 03.05.2007 */ -//todo it's not actually a compiler anymore, remove all the implements' -public class GroovyToJavaGenerator implements SourceGeneratingCompiler, CompilationStatusListener { +public class GroovyToJavaGenerator { private static final Map typesToInitialValues = new HashMap(); private static final Logger LOG = Logger.getInstance("org.jetbrains.plugins.groovy.compiler.generator.GroovyToJavaGenerator"); @@ -100,12 +103,6 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat PsiModifier.VOLATILE }; - private static final String[] JAVA_TYPE_DEFINITION_MODIFIERS = new String[]{ - PsiModifier.PUBLIC, - PsiModifier.ABSTRACT, - PsiModifier.FINAL - }; - private static final CharSequence PREFIX_SEPARATOR = "/"; private final CompileContext myContext; private final Project myProject; @@ -149,7 +146,7 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat //top level class if (needCreateTopLevelClass) { - generationItems.add(new GenerationItemImpl(prefix + file.getNameWithoutExtension() + "." + "java", module, new TimestampValidityState(file.getTimeStamp()), isInTestSources, file)); + generationItems.add(new GenerationItem(prefix + file.getNameWithoutExtension() + "." + "java", module, new TimestampValidityState(file.getTimeStamp()), isInTestSources, file)); } GrTypeDefinition[] typeDefinitions = ApplicationManager.getApplication().runReadAction(new Computable() { @@ -159,7 +156,7 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat }); for (GrTypeDefinition typeDefinition : typeDefinitions) { - item = new GenerationItemImpl(prefix + typeDefinition.getName() + "." + "java", module, new TimestampValidityState(file.getTimeStamp()), isInTestSources, file); + item = new GenerationItem(prefix + typeDefinition.getName() + "." + "java", module, new TimestampValidityState(file.getTimeStamp()), isInTestSources, file); generationItems.add(item); } } @@ -181,7 +178,7 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat return VfsUtil.toVirtualFileArray(set); } - public GenerationItem[] generate(CompileContext context, GenerationItem[] itemsToGenerate, VirtualFile outputRootDirectory) { + public GenerationItem[] generate(GenerationItem[] itemsToGenerate, VirtualFile outputRootDirectory) { List generatedItems = new ArrayList(); Map pathsToItemsMap = new HashMap(); @@ -192,7 +189,7 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat Set vFiles = new HashSet(); for (GenerationItem item : itemsToGenerate) { - vFiles.add(((GenerationItemImpl) item).getVFile()); + vFiles.add(item.getVFile()); } for (VirtualFile vFile : vFiles) { @@ -270,19 +267,19 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat !classNames.contains(StringUtil.decapitalize(fileDefinitionName))) { final PsiClass scriptClass = file.getScriptClass(); if (scriptClass != null) { - generatedItemsRelativePaths.add(createJavaSourceFile(outputRootDirectory, file, scriptClass, packageDefinition)); + generatedItemsRelativePaths.add(createJavaSourceFile(outputRootDirectory, scriptClass, packageDefinition)); } } } for (final GrTypeDefinition typeDefinition : file.getTypeDefinitions()) { - generatedItemsRelativePaths.add(createJavaSourceFile(outputRootDirectory, file, typeDefinition, packageDefinition)); + generatedItemsRelativePaths.add(createJavaSourceFile(outputRootDirectory, typeDefinition, packageDefinition)); } return generatedItemsRelativePaths; } - private static String getJavaClassPackage(GrPackageDefinition packageDefinition) { + private static String getJavaClassPackage(@Nullable GrPackageDefinition packageDefinition) { if (packageDefinition == null) return ""; String prefix = packageDefinition.getPackageName(); @@ -292,24 +289,43 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat return prefix; } - private String createJavaSourceFile(VirtualFile outputRootDirectory, GroovyFileBase file, @NotNull PsiClass typeDefinition, GrPackageDefinition packageDefinition) { - //prefix defines structure of directories tree - String prefix = ""; - if (packageDefinition != null) { - prefix = getJavaClassPackage(packageDefinition); + private String createJavaSourceFile(VirtualFile outputRootDirectory, @NotNull PsiClass typeDefinition, GrPackageDefinition packageDefinition) { + StringBuffer text = new StringBuffer(); + writeTypeDefinition(text, typeDefinition, packageDefinition, true); + + String prefix = getJavaClassPackage(packageDefinition); + String outputDir = outputRootDirectory.getPath(); + String fileName = typeDefinition.getName() + "." + "java"; + + String prefixWithoutSeparator = prefix; + + if (!"".equals(prefix)) { + prefixWithoutSeparator = prefix.substring(0, prefix.length() - PREFIX_SEPARATOR.length()); + new File(outputDir, prefixWithoutSeparator).mkdirs(); } - StringBuffer text = new StringBuffer(); + File myFile; + if (!"".equals(prefix)) + myFile = new File(outputDir + File.separator + prefixWithoutSeparator, fileName); + else + myFile = new File(outputDir, fileName); - final String typeDefinitionName = typeDefinition.getName(); - writeTypeDefinition(text, typeDefinitionName, typeDefinition, packageDefinition); - - VirtualFile virtualFile = file.getVirtualFile(); - assert virtualFile != null; -// String generatedFileRelativePath = prefix + typeDefinitionName + "." + "java"; - String fileShortName = typeDefinitionName + "." + "java"; - createGeneratedFile(text, outputRootDirectory.getPath(), prefix, fileShortName); - return prefix + typeDefinitionName + "." + "java"; + BufferedWriter writer = null; + try { + Writer fileWriter = new FileWriter(myFile); + writer = new BufferedWriter(fileWriter); + writer.write(text.toString()); + } catch (IOException e) { + LOG.error(e); + } finally { + try { + assert writer != null; + writer.close(); + } catch (IOException e) { + LOG.error(e); + } + } + return prefix + fileName; } private static GrTopStatement[] getTopStatementsInReadAction(final GroovyFileBase myPsiFile) { @@ -333,7 +349,8 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat return isOnlyInnerTypeDef; } - private void writeTypeDefinition(StringBuffer text, String typeDefinitionName, @NotNull PsiClass typeDefinition, GrPackageDefinition packageDefinition) { + private void writeTypeDefinition(StringBuffer text, @NotNull PsiClass typeDefinition, + @Nullable GrPackageDefinition packageDefinition, boolean toplevel) { final boolean isScript = typeDefinition instanceof GroovyScriptClass; writePackageStatement(text, packageDefinition); @@ -345,39 +362,26 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat boolean isEnum = typeDefinition instanceof GrEnumTypeDefinition; boolean isAtInterface = typeDefinition instanceof GrAnnotationTypeDefinition; - - PsiModifierList modifierList = typeDefinition.getModifierList(); - - boolean wasAddedModifiers = modifierList != null && writeTypeDefinitionMethodModifiers(text, modifierList, JAVA_TYPE_DEFINITION_MODIFIERS, typeDefinition.isInterface()); - if (!wasAddedModifiers) { - text.append("public "); - } + writeClassModifiers(text, typeDefinition.getModifierList(), typeDefinition.isInterface(), toplevel); if (isInterface) text.append("interface"); else if (isEnum) text.append("enum"); else if (isAtInterface) text.append("@interface"); else text.append("class"); - text.append(" "); + text.append(" ").append(typeDefinition.getName()); - text.append(typeDefinitionName); - - if (typeDefinition != null) { - appendTypeParameters(text, typeDefinition); - } + appendTypeParameters(text, typeDefinition); text.append(" "); if (isScript) { - text.append("extends "); - text.append("groovy.lang.Script "); + text.append("extends groovy.lang.Script "); } else if (!isEnum && !isAtInterface) { final PsiClassType[] extendsClassesTypes = typeDefinition.getExtendsListTypes(); if (extendsClassesTypes.length > 0) { - text.append("extends "); - text.append(computeTypeText(extendsClassesTypes[0], false)); - text.append(" "); + text.append("extends ").append(computeTypeText(extendsClassesTypes[0], false)).append(" "); } PsiClassType[] implementsTypes = typeDefinition.getImplementsListTypes(); @@ -386,8 +390,7 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat int i = 0; while (i < implementsTypes.length) { if (i > 0) text.append(", "); - text.append(computeTypeText(implementsTypes[i], false)); - text.append(" "); + text.append(computeTypeText(implementsTypes[i], false)).append(" "); i++; } } @@ -457,6 +460,10 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat writeVariableDeclarations(text, (GrVariableDeclaration) declaration); } } + for (PsiClass inner : typeDefinition.getInnerClasses()) { + writeTypeDefinition(text, inner, null, false); + text.append("\n"); + } text.append("}"); } @@ -527,7 +534,7 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat } } - private void writeConstructor(final StringBuffer text, final GrConstructor constructor, boolean isEnum) { + private static void writeConstructor(final StringBuffer text, final GrConstructor constructor, boolean isEnum) { text.append("\n"); text.append(" "); if (!isEnum) { @@ -543,23 +550,16 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat GrParameter[] parameterList = constructor.getParameters(); text.append("("); - String paramType; - GrTypeElement paramTypeElement; for (int i = 0; i < parameterList.length; i++) { if (i > 0) text.append(", "); GrParameter parameter = parameterList[i]; - paramTypeElement = parameter.getTypeElementGroovy(); - paramType = getTypeText(paramTypeElement); - text.append(paramType); - text.append(" "); - text.append(parameter.getName()); + text.append(getTypeText(parameter.getTypeElementGroovy())).append(" ").append(parameter.getName()); } - text.append(")"); - text.append(" "); + text.append(") "); /************* body **********/ @@ -744,27 +744,32 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat } } - private static boolean writeTypeDefinitionMethodModifiers(StringBuffer text, PsiModifierList modifierList, String[] modifiers, boolean isInterface) { - boolean wasAddedModifiers = false; - for (String modifierType : modifiers) { - if (modifierList.hasModifierProperty(modifierType)) { - if (PsiModifier.ABSTRACT.equals(modifierType) && isInterface) { - continue; + private static void writeClassModifiers(StringBuffer text, + @Nullable PsiModifierList modifierList, boolean isInterface, boolean toplevel) { + if (modifierList == null || modifierList.hasModifierProperty(PsiModifier.PUBLIC)) { + text.append("public "); + } + + if (modifierList != null) { + List allowedModifiers = new ArrayList(); + allowedModifiers.add(PsiModifier.FINAL); + if (!toplevel) { + allowedModifiers.addAll(Arrays.asList(PsiModifier.PROTECTED, PsiModifier.PRIVATE, PsiModifier.STATIC)); + } + if (!isInterface) { + allowedModifiers.add(PsiModifier.ABSTRACT); + } + + for (String modifierType : allowedModifiers) { + if (modifierList.hasModifierProperty(modifierType)) { + text.append(modifierType).append(" "); } - text.append(modifierType); - text.append(" "); - wasAddedModifiers = true; } } - return wasAddedModifiers; } private static String getTypeText(GrTypeElement typeElement) { - if (typeElement == null) { - return "java.lang.Object"; - } else { - return computeTypeText(typeElement.getType(), false); - } + return getTypeText(typeElement == null ? null : typeElement.getType(), false); } private static String getTypeText(PsiType type, boolean allowVarargs) { @@ -786,66 +791,16 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat return canonicalText != null ? canonicalText : type.getPresentableText(); } - private static void createGeneratedFile(StringBuffer text, String outputDir, String prefix, String generatedItemPath) { - assert prefix != null; - - String prefixWithoutSeparator = prefix; - - if (!"".equals(prefix)) { - prefixWithoutSeparator = prefix.substring(0, prefix.length() - PREFIX_SEPARATOR.length()); - new File(outputDir, prefixWithoutSeparator).mkdirs(); - } - - File myFile; - if (!"".equals(prefix)) - myFile = new File(outputDir + File.separator + prefixWithoutSeparator, generatedItemPath); - else - myFile = new File(outputDir, generatedItemPath); - - BufferedWriter writer = null; - try { - Writer fileWriter = new FileWriter(myFile); - writer = new BufferedWriter(fileWriter); - writer.write(text.toString()); - } catch (IOException e) { - LOG.error(e); - } finally { - try { - assert writer != null; - writer.close(); - } catch (IOException e) { - LOG.error(e); - } - } - } - - @NotNull - public String getDescription() { - return "Groovy to java source code generator"; - } - - public boolean validateConfiguration(CompileScope scope) { - return true; - } - CharTrie myTrie = new CharTrie(); - public void compilationFinished(boolean aborted, int errors, int warnings, final CompileContext compileContext) { - myTrie.clear(); - } - - public ValidityState createValidityState(DataInput in) throws IOException { - return TimestampValidityState.load(in); - } - - class GenerationItemImpl implements GenerationItem { + public class GenerationItem { ValidityState myState; private final boolean myInTestSources; final Module myModule; public int myHashCode; private final VirtualFile myVFile; - public GenerationItemImpl(String path, Module module, ValidityState state, boolean isInTestSources, VirtualFile vFile) { + public GenerationItem(String path, Module module, ValidityState state, boolean isInTestSources, VirtualFile vFile) { myVFile = vFile; myModule = module; myState = state; @@ -857,18 +812,10 @@ public class GroovyToJavaGenerator implements SourceGeneratingCompiler, Compilat return myTrie.getString(myHashCode); } - public ValidityState getValidityState() { - return myState; - } - public Module getModule() { return myModule; } - public boolean isTestSource() { - return myInTestSources; - } - public VirtualFile getVFile() { return myVFile; } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTest.groovy index b79dbed29bb1..fff8d04f1871 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTest.groovy @@ -263,7 +263,7 @@ public class GroovyCompilerTest extends GroovyCompilerTestCase { Module dep = addDependentModule(); - addGroovyLibrary(dep); + addGroovyLibrary(dep, false); assertEmpty(make()); assertOutput("Bar", "239", dep); @@ -278,5 +278,14 @@ public class GroovyCompilerTest extends GroovyCompilerTestCase { assertEmpty make() } + public void test1_7InnerClass() throws Exception { + myFixture.addFileToProject "Foo.groovy", """ +class Foo { + static class Bar {} +}""" + myFixture.addFileToProject "AJava.java", "public class AJava extends Foo.Bar {}" + assertEmpty make() + } + } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTestCase.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTestCase.java index 40ee7703a893..8e06fa9b6bf5 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTestCase.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyCompilerTestCase.java @@ -43,6 +43,7 @@ import com.intellij.util.concurrency.Semaphore; import org.jetbrains.plugins.groovy.compiler.GroovyCompilerLoader; import org.jetbrains.plugins.groovy.config.GroovyConfigUtils; import org.jetbrains.plugins.groovy.util.GroovyUtils; +import org.jetbrains.plugins.groovy.util.TestUtils; import java.io.File; import java.io.IOException; @@ -65,7 +66,7 @@ public abstract class GroovyCompilerTestCase extends JavaCodeInsightFixtureTestC CompilerProjectExtension.getInstance(getProject()).setCompilerOutputUrl(myMainOutput.findOrCreateDir("out").getUrl()); - addGroovyLibrary(myModule); + addGroovyLibrary(myModule, getName().contains("1_7")); } @Override @@ -74,8 +75,8 @@ public abstract class GroovyCompilerTestCase extends JavaCodeInsightFixtureTestC super.tuneFixture(moduleBuilder); } - protected static void addGroovyLibrary(final Module to) { - final String root = PathManager.getHomePath() + "/community/lib/"; + protected static void addGroovyLibrary(final Module to, boolean version17) { + final String root = version17 ? TestUtils.getRealGroovy1_7LibraryHome() : PathManager.getHomePath() + "/community/lib/"; final File[] groovyJars = GroovyUtils.getFilesInDirectoryByPattern(root, GroovyConfigUtils.GROOVY_ALL_JAR_PATTERN); assert groovyJars.length == 1; PsiTestUtil.addLibrary(to, "groovy", root, groovyJars[0].getName()); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/generator/GeneratorTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/generator/GeneratorTest.java index f44c61eba164..4d0a379bc786 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/generator/GeneratorTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/generator/GeneratorTest.java @@ -1,15 +1,14 @@ package org.jetbrains.plugins.groovy.lang.generator; import com.intellij.openapi.compiler.CompileContext; -import com.intellij.openapi.compiler.GeneratingCompiler; import com.intellij.openapi.module.Module; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; +import com.intellij.testFramework.builders.JavaModuleFixtureBuilder; import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase; import com.intellij.testFramework.fixtures.TempDirTestFixture; -import com.intellij.testFramework.builders.JavaModuleFixtureBuilder; import com.intellij.util.IncorrectOperationException; import org.jetbrains.plugins.groovy.compiler.generator.GroovyToJavaGenerator; import org.jetbrains.plugins.groovy.util.TestUtils; @@ -77,15 +76,15 @@ public void testArrayType1() throws Throwable { doTest(); } final StringBuffer buffer = new StringBuffer(); final GroovyToJavaGeneratorTester groovyToJavaGeneratorTester = new GroovyToJavaGeneratorTester(relTestPath, data.get(0), getProject()); - final GeneratingCompiler.GenerationItem[][] generatedItems = new GeneratingCompiler.GenerationItem[1][1]; + final GroovyToJavaGenerator.GenerationItem[][] generatedItems = new GroovyToJavaGenerator.GenerationItem[1][1]; - GeneratingCompiler.GenerationItem[] generationItems = groovyToJavaGeneratorTester.getGenerationItems(null); + GroovyToJavaGenerator.GenerationItem[] generationItems = groovyToJavaGeneratorTester.getGenerationItems(null); VirtualFile outputDirVirtualFile = tempDirFixture.getFile(""); - generatedItems[0] = groovyToJavaGeneratorTester.generate(null, generationItems, outputDirVirtualFile); + generatedItems[0] = groovyToJavaGeneratorTester.generate(generationItems, outputDirVirtualFile); - for (GeneratingCompiler.GenerationItem generatedItem : generatedItems[0]) { + for (GroovyToJavaGenerator.GenerationItem generatedItem : generatedItems[0]) { final String path = tempDirFixture.getTempDirPath() + File.separator + generatedItem.getPath(); BufferedReader reader = new BufferedReader(new FileReader(path)); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/util/TestUtils.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/util/TestUtils.java index eb5aad60edf2..d8ca5fd0c791 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/util/TestUtils.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/util/TestUtils.java @@ -58,6 +58,10 @@ public abstract class TestUtils { return getAbsoluteTestDataPath() + "/mockGroovyLib1.7"; } + public static String getRealGroovy1_7LibraryHome() { + return getAbsoluteTestDataPath() + "/realGroovy17/"; + } + public static String getMockGroovy1_7LibraryName() { return getMockGroovy1_7LibraryHome()+"/groovy-all-1.7.jar"; } diff --git a/plugins/groovy/testdata/realGroovy17/groovy-all-1.7.0.jar b/plugins/groovy/testdata/realGroovy17/groovy-all-1.7.0.jar new file mode 100644 index 000000000000..936a24ba9f02 Binary files /dev/null and b/plugins/groovy/testdata/realGroovy17/groovy-all-1.7.0.jar differ diff --git a/xml/impl/src/com/intellij/html/impl/RelaxedHtmlFromSchemaElementDescriptor.java b/xml/impl/src/com/intellij/html/impl/RelaxedHtmlFromSchemaElementDescriptor.java index c4e70f412b15..396d12e6863f 100644 --- a/xml/impl/src/com/intellij/html/impl/RelaxedHtmlFromSchemaElementDescriptor.java +++ b/xml/impl/src/com/intellij/html/impl/RelaxedHtmlFromSchemaElementDescriptor.java @@ -16,6 +16,7 @@ package com.intellij.html.impl; import com.intellij.openapi.extensions.Extensions; +import com.intellij.psi.xml.XmlAttribute; import com.intellij.psi.xml.XmlTag; import com.intellij.util.ArrayUtil; import com.intellij.xml.XmlAttributeDescriptor; @@ -82,6 +83,11 @@ public class RelaxedHtmlFromSchemaElementDescriptor extends XmlElementDescriptor return descriptors; } + @Override + public XmlAttributeDescriptor getAttributeDescriptor(XmlAttribute attribute) { + return getAttributeDescriptor(attribute.getName(), attribute.getParent()); + } + public XmlAttributeDescriptor getAttributeDescriptor(String attributeName, final XmlTag context) { final XmlAttributeDescriptor descriptor = super.getAttributeDescriptor(attributeName.toLowerCase(), context); if (descriptor != null) return descriptor; diff --git a/xml/impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java b/xml/impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java index 7b378c71fd8d..d231ea7cc1c9 100644 --- a/xml/impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java +++ b/xml/impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java @@ -156,15 +156,17 @@ public class XmlElementDescriptorImpl implements XmlElementDescriptor, PsiWritab return nsDescriptor; } + @Nullable public TypeDescriptor getType() { return getType(null); } + @Nullable public TypeDescriptor getType(XmlElement context) { final XmlNSDescriptor nsDescriptor = getNSDescriptor(context); - if (!(nsDescriptor instanceof XmlNSDescriptorImpl)) return null; + if (!(nsDescriptor instanceof XmlNSTypeDescriptorProvider)) return null; - TypeDescriptor type = ((XmlNSDescriptorImpl) nsDescriptor).getTypeDescriptor(myDescriptorTag); + TypeDescriptor type = ((XmlNSTypeDescriptorProvider) nsDescriptor).getTypeDescriptor(myDescriptorTag); if (type == null) { String substAttr = myDescriptorTag.getAttributeValue("substitutionGroup"); if (substAttr != null) { diff --git a/xml/impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java b/xml/impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java index d1a88adfbb01..d387b63c3969 100644 --- a/xml/impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java +++ b/xml/impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java @@ -48,7 +48,7 @@ import java.util.*; * @author Mike */ @SuppressWarnings({"HardCodedStringLiteral"}) -public class XmlNSDescriptorImpl implements XmlNSDescriptor,Validator, DumbAware { +public class XmlNSDescriptorImpl implements XmlNSDescriptor,Validator, DumbAware, XmlNSTypeDescriptorProvider { @NonNls private static final Set STD_TYPES = new HashSet(); private static final Set UNDECLARED_STD_TYPES = new HashSet(); private XmlFile myFile; @@ -335,7 +335,7 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptor,Validator visited) { XmlNSDescriptorImpl responsibleDescriptor = this; if (namespace != null && namespace.length() != 0 && !namespace.equals(getDefaultNamespace())) { diff --git a/xml/impl/src/com/intellij/xml/impl/schema/XmlNSTypeDescriptorProvider.java b/xml/impl/src/com/intellij/xml/impl/schema/XmlNSTypeDescriptorProvider.java new file mode 100644 index 000000000000..1d82db04c697 --- /dev/null +++ b/xml/impl/src/com/intellij/xml/impl/schema/XmlNSTypeDescriptorProvider.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2010 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.xml.impl.schema; + +import com.intellij.psi.xml.XmlTag; +import org.jetbrains.annotations.Nullable; + +/** + * @author nik + */ +public interface XmlNSTypeDescriptorProvider { + @Nullable + TypeDescriptor getTypeDescriptor(String name, XmlTag context); + + @Nullable + TypeDescriptor getTypeDescriptor(XmlTag descriptorTag); +} diff --git a/xml/impl/src/com/intellij/xml/index/XmlNamespaceIndex.java b/xml/impl/src/com/intellij/xml/index/XmlNamespaceIndex.java index acc93470cc5d..d4ab74b2d39d 100644 --- a/xml/impl/src/com/intellij/xml/index/XmlNamespaceIndex.java +++ b/xml/impl/src/com/intellij/xml/index/XmlNamespaceIndex.java @@ -38,7 +38,7 @@ import java.util.Map; public class XmlNamespaceIndex extends XmlIndex { @Nullable - public static String getNamespace(VirtualFile file, final Project project) { + public static String getNamespace(@NotNull VirtualFile file, final Project project) { final List list = FileBasedIndex.getInstance().getValues(NAME, file.getUrl(), createFilter(project)); return list.size() == 0 ? null : list.get(0); }