diff --git a/compiler/frontend/src/org/jetbrains/jet/JetNodeTypes.java b/compiler/frontend/src/org/jetbrains/jet/JetNodeTypes.java index 04839a4ba85..aabba80665c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/JetNodeTypes.java +++ b/compiler/frontend/src/org/jetbrains/jet/JetNodeTypes.java @@ -148,4 +148,7 @@ public interface JetNodeTypes { JetNodeType SCRIPT = new JetNodeType("SCRIPT", JetScript.class); JetNodeType IDE_TEMPLATE_EXPRESSION = new JetNodeType("IDE_TEMPLATE_EXPRESSION", JetIdeTemplate.class); + + IFileElementType TYPE_CODE_FRAGMENT = new JetTypeCodeFragmentType(); + IFileElementType EXPRESSION_CODE_FRAGMENT = new JetExpressionCodeFragmentType(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParser.java b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParser.java index d05977a8662..ba3556879da 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParser.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParser.java @@ -19,10 +19,8 @@ package org.jetbrains.jet.lang.parsing; import com.intellij.lang.ASTNode; import com.intellij.lang.PsiBuilder; import com.intellij.lang.PsiParser; -import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; -import com.intellij.psi.impl.file.impl.JavaFileManager; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; @@ -53,4 +51,18 @@ public class JetParser implements PsiParser { } return psiBuilder.getTreeBuilt(); } + + @NotNull + public static ASTNode parseTypeCodeFragment(PsiBuilder psiBuilder) { + JetParsing jetParsing = JetParsing.createForTopLevel(new SemanticWhitespaceAwarePsiBuilderImpl(psiBuilder)); + jetParsing.parseTypeCodeFragment(); + return psiBuilder.getTreeBuilt(); + } + + @NotNull + public static ASTNode parseExpressionCodeFragment(PsiBuilder psiBuilder) { + JetParsing jetParsing = JetParsing.createForTopLevel(new SemanticWhitespaceAwarePsiBuilderImpl(psiBuilder)); + jetParsing.parseExpressionCodeFragment(); + return psiBuilder.getTreeBuilt(); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParserDefinition.java b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParserDefinition.java index cad2aca6b7f..52bba964f59 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParserDefinition.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParserDefinition.java @@ -16,6 +16,7 @@ package org.jetbrains.jet.lang.parsing; +import com.intellij.extapi.psi.ASTWrapperPsiElement; import com.intellij.lang.ASTNode; import com.intellij.lang.LanguageParserDefinitions; import com.intellij.lang.ParserDefinition; @@ -25,25 +26,19 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IFileElementType; import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.JetNodeType; +import org.jetbrains.jet.JetNodeTypes; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.stubs.elements.JetStubElementType; import org.jetbrains.jet.lang.psi.stubs.elements.JetStubElementTypes; -import org.jetbrains.jet.lang.resolve.AnalyzerScriptParameter; -import org.jetbrains.jet.lang.resolve.name.Name; -import org.jetbrains.jet.lang.types.ref.JetTypeName; import org.jetbrains.jet.lexer.JetLexer; import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.plugin.JetLanguage; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - public class JetParserDefinition implements ParserDefinition { public static final String KTSCRIPT_FILE_SUFFIX = "ktscript"; @@ -96,11 +91,17 @@ public class JetParserDefinition implements ParserDefinition { @Override @NotNull public PsiElement createElement(ASTNode astNode) { - if (astNode.getElementType() instanceof JetStubElementType) { - return ((JetStubElementType) astNode.getElementType()).createPsiFromAst(astNode); - } + IElementType elementType = astNode.getElementType(); - return ((JetNodeType) astNode.getElementType()).createPsi(astNode); + if (elementType instanceof JetStubElementType) { + return ((JetStubElementType) elementType).createPsiFromAst(astNode); + } + else if (elementType == JetNodeTypes.TYPE_CODE_FRAGMENT || elementType == JetNodeTypes.EXPRESSION_CODE_FRAGMENT) { + return new ASTWrapperPsiElement(astNode); + } + else { + return ((JetNodeType) elementType).createPsi(astNode); + } } @Override diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java index 526e41fae7a..d73aea15f5c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java @@ -98,6 +98,30 @@ public class JetParsing extends AbstractJetParsing { fileMarker.done(JET_FILE); } + void parseTypeCodeFragment() { + PsiBuilder.Marker marker = mark(); + parseTypeRef(); + + while (!eof()) { + error("unexpected symbol"); + advance(); + } + + marker.done(TYPE_CODE_FRAGMENT); + } + + void parseExpressionCodeFragment() { + PsiBuilder.Marker marker = mark(); + myExpressionParsing.parseExpression(); + + while (!eof()) { + error("unexpected symbol"); + advance(); + } + + marker.done(EXPRESSION_CODE_FRAGMENT); + } + void parseScript() { PsiBuilder.Marker fileMarker = mark(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetCodeFragmentImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetCodeFragmentImpl.java new file mode 100644 index 00000000000..e8c7450a03f --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetCodeFragmentImpl.java @@ -0,0 +1,71 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.psi; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiManagerEx; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.tree.IElementType; +import com.intellij.testFramework.LightVirtualFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.plugin.JetFileType; + +public class JetCodeFragmentImpl extends JetFile implements PsiCodeFragment { + protected PsiElement context; + private GlobalSearchScope resolveScope; + + public JetCodeFragmentImpl(Project project, String name, CharSequence text, IElementType elementType, PsiElement context) { + super(((PsiManagerEx) PsiManager.getInstance(project)).getFileManager().createFileViewProvider( + new LightVirtualFile(name, JetFileType.INSTANCE, text), true)); + ((SingleRootFileViewProvider)getViewProvider()).forceCachedPsi(this); + init(TokenType.CODE_FRAGMENT, elementType); + this.context = context; + } + + @Override + public void forceResolveScope(GlobalSearchScope scope) { + resolveScope = scope; + } + + @Override + public GlobalSearchScope getForcedResolveScope() { + return resolveScope; + } + + @Override + public boolean isPhysical() { + return true; + } + + @Override + public boolean isValid() { + return true; + } + + @Override + public PsiElement getContext() { + return context; + } + + @Override + @NotNull + public GlobalSearchScope getResolveScope() { + if (resolveScope != null) return resolveScope; + return super.getResolveScope(); + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetExpressionCodeFragment.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetExpressionCodeFragment.java new file mode 100644 index 00000000000..079a61416ee --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetExpressionCodeFragment.java @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.psi; + +import com.intellij.psi.PsiCodeFragment; +import org.jetbrains.annotations.Nullable; + +public interface JetExpressionCodeFragment extends PsiCodeFragment { + @Nullable + JetExpression getExpression(); +} + diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetExpressionCodeFragmentImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetExpressionCodeFragmentImpl.java new file mode 100644 index 00000000000..c39691a2906 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetExpressionCodeFragmentImpl.java @@ -0,0 +1,39 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.psi; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.JetNodeTypes; + +public class JetExpressionCodeFragmentImpl extends JetCodeFragmentImpl implements JetExpressionCodeFragment { + public JetExpressionCodeFragmentImpl( + Project project, + String name, + CharSequence text, + PsiElement context + ) { + super(project, name, text, JetNodeTypes.EXPRESSION_CODE_FRAGMENT, context); + } + + @Override + @Nullable + public JetExpression getExpression() { + return findChildByClass(JetExpression.class); + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetExpressionCodeFragmentType.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetExpressionCodeFragmentType.java new file mode 100644 index 00000000000..03d1b30bfbb --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetExpressionCodeFragmentType.java @@ -0,0 +1,49 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.psi; + +import com.intellij.lang.ASTNode; +import com.intellij.lang.Language; +import com.intellij.lang.PsiBuilder; +import com.intellij.lang.PsiBuilderFactory; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.parsing.JetParser; +import org.jetbrains.jet.lang.psi.stubs.elements.JetFileElementType; + +public class JetExpressionCodeFragmentType extends JetFileElementType { + private static final String NAME = "jet.EXPRESSION_CODE_FRAGMENT"; + + public JetExpressionCodeFragmentType() { + super(NAME); + } + + @Override + public String getExternalId() { + return NAME; + } + + @Override + protected ASTNode doParseContents(@NotNull ASTNode chameleon, @NotNull PsiElement psi) { + Project project = psi.getProject(); + Language languageForParser = getLanguageForParser(psi); + PsiBuilder builder = PsiBuilderFactory.getInstance().createBuilder(project, chameleon, null, languageForParser, chameleon.getChars()); + return JetParser.parseExpressionCodeFragment(builder); + } +} + diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java index 3be10ab7cbc..ef7d39401ce 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -246,4 +246,12 @@ public class JetPsiFactory { return assignment; } + + public static JetTypeCodeFragment createTypeCodeFragment(Project project, String text, PsiElement context) { + return new JetTypeCodeFragmentImpl(project, "fragment.kt", text, context); + } + + public static JetExpressionCodeFragment createExpressionCodeFragment(Project project, String text, PsiElement context) { + return new JetExpressionCodeFragmentImpl(project, "fragment.kt", text, context); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeCodeFragment.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeCodeFragment.java new file mode 100644 index 00000000000..ab01531002b --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeCodeFragment.java @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.psi; + +import com.intellij.psi.PsiCodeFragment; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.types.JetType; + +public interface JetTypeCodeFragment extends PsiCodeFragment { + @Nullable + JetType getType(); +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeCodeFragmentImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeCodeFragmentImpl.java new file mode 100644 index 00000000000..391ba3c916e --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeCodeFragmentImpl.java @@ -0,0 +1,58 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.psi; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.JetNodeTypes; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; +import org.jetbrains.jet.lexer.JetTokens; + +public class JetTypeCodeFragmentImpl extends JetCodeFragmentImpl implements JetTypeCodeFragment { + public JetTypeCodeFragmentImpl(Project project, String name, CharSequence text, PsiElement context) { + super(project, name, text, JetNodeTypes.TYPE_CODE_FRAGMENT, context); + } + + @Nullable + @Override + public JetType getType() { + JetType type = null; + + for (PsiElement child : getChildren()) { + IElementType elementType = child.getNode().getElementType(); + + if (elementType == JetNodeTypes.TYPE_CODE_FRAGMENT) { + for (PsiElement grChild : child.getChildren()) { + if (grChild instanceof JetTypeReference) { + if (!grChild.getText().isEmpty()) + //TODO return the actual type + type = KotlinBuiltIns.getInstance().getAnyType(); + } + else if (!JetTokens.WHITE_SPACE_OR_COMMENT_BIT_SET.contains(elementType)) + return null; + } + } + else if (!JetTokens.WHITE_SPACE_OR_COMMENT_BIT_SET.contains(elementType)) + return null; + } + + return type; + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeCodeFragmentType.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeCodeFragmentType.java new file mode 100644 index 00000000000..1e538cff514 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeCodeFragmentType.java @@ -0,0 +1,48 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.psi; + +import com.intellij.lang.ASTNode; +import com.intellij.lang.Language; +import com.intellij.lang.PsiBuilder; +import com.intellij.lang.PsiBuilderFactory; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.parsing.JetParser; +import org.jetbrains.jet.lang.psi.stubs.elements.JetFileElementType; + +public class JetTypeCodeFragmentType extends JetFileElementType { + private static final String NAME = "jet.TYPE_CODE_FRAGMENT"; + + public JetTypeCodeFragmentType() { + super(NAME); + } + + @Override + public String getExternalId() { + return NAME; + } + + @Override + protected ASTNode doParseContents(@NotNull ASTNode chameleon, @NotNull PsiElement psi) { + Project project = psi.getProject(); + Language languageForParser = getLanguageForParser(psi); + PsiBuilder builder = PsiBuilderFactory.getInstance().createBuilder(project, chameleon, null, languageForParser, chameleon.getChars()); + return JetParser.parseTypeCodeFragment(builder); + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/stubs/elements/JetFileElementType.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/stubs/elements/JetFileElementType.java index 94d7da8d493..7ce973d4f8b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/stubs/elements/JetFileElementType.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/stubs/elements/JetFileElementType.java @@ -26,6 +26,7 @@ import com.intellij.psi.stubs.StubInputStream; import com.intellij.psi.stubs.StubOutputStream; import com.intellij.psi.tree.IStubFileElementType; import com.intellij.util.io.StringRef; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.parsing.JetParser; import org.jetbrains.jet.lang.psi.stubs.PsiJetFileStub; @@ -41,6 +42,10 @@ public class JetFileElementType extends IStubFileElementType { super("jet.FILE", JetLanguage.INSTANCE); } + protected JetFileElementType(@NonNls String debugName) { + super(debugName, JetLanguage.INSTANCE); + } + @Override public StubBuilder getBuilder() { return new JetFileStubBuilder(); @@ -79,7 +84,6 @@ public class JetFileElementType extends IStubFileElementType { return parser.parse(this, builder, psi.getContainingFile()).getFirstChildNode(); } - @Override public void indexStub(PsiJetFileStub stub, IndexSink sink) { StubIndexServiceFactory.getInstance().indexFile(stub, sink);