Skip to content
This repository has been archived by the owner on Sep 16, 2022. It is now read-only.

Commit

Permalink
feat(Compiler): Add support for 'exports', to access statics in a tem…
Browse files Browse the repository at this point in the history
…plate.

This initial version does not support library prefixes.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=156573102
  • Loading branch information
harryterkelsen authored and matanlurey committed May 24, 2017
1 parent 7159c81 commit 0a28527
Show file tree
Hide file tree
Showing 14 changed files with 388 additions and 100 deletions.
10 changes: 10 additions & 0 deletions lib/src/compiler/compile_metadata.dart
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@ class CompileDirectiveMetadata implements CompileMetadataWithType {
// CompileProviderMetadata | CompileTypeMetadata |
// CompileIdentifierMetadata | List
List viewProviders,
List<CompileIdentifierMetadata> exports,
List<CompileQueryMetadata> queries,
List<CompileQueryMetadata> viewQueries,
CompileTemplateMetadata template}) {
Expand Down Expand Up @@ -582,6 +583,7 @@ class CompileDirectiveMetadata implements CompileMetadataWithType {
lifecycleHooks: lifecycleHooks ?? <LifecycleHooks>[],
providers: providers,
viewProviders: viewProviders,
exports: exports,
queries: queries,
viewQueries: viewQueries,
template: template);
Expand All @@ -602,6 +604,7 @@ class CompileDirectiveMetadata implements CompileMetadataWithType {
List<LifecycleHooks> lifecycleHooks;
List<CompileProviderMetadata> providers;
List<CompileProviderMetadata> viewProviders;
List<CompileIdentifierMetadata> exports;
List<CompileQueryMetadata> queries;
List<CompileQueryMetadata> viewQueries;
CompileTemplateMetadata template;
Expand All @@ -624,12 +627,14 @@ class CompileDirectiveMetadata implements CompileMetadataWithType {
// CompileProviderMetadata | CompileTypeMetadata |
// CompileIdentifierMetadata | List
List viewProviders,
List exports,
List<CompileQueryMetadata> queries,
List<CompileQueryMetadata> viewQueries,
CompileTemplateMetadata template}) {
this.lifecycleHooks = lifecycleHooks ?? [];
this.providers = providers as List<CompileProviderMetadata> ?? [];
this.viewProviders = viewProviders as List<CompileProviderMetadata> ?? [];
this.exports = exports as List<CompileIdentifierMetadata> ?? [];
this.queries = queries ?? [];
this.viewQueries = viewQueries ?? [];
this.template = template;
Expand Down Expand Up @@ -664,6 +669,9 @@ class CompileDirectiveMetadata implements CompileMetadataWithType {
: data['template'],
providers: _arrayFromJson(data['providers'], metadataFromJson),
viewProviders: _arrayFromJson(data['viewProviders'], metadataFromJson),
exports:
_arrayFromJson(data['exports'], CompileIdentifierMetadata.fromJson)
as List<CompileIdentifierMetadata>,
queries: _arrayFromJson(data['queries'], CompileQueryMetadata.fromJson)
as List<CompileQueryMetadata>,
viewQueries:
Expand All @@ -689,6 +697,7 @@ class CompileDirectiveMetadata implements CompileMetadataWithType {
'template': template?.toJson(),
'providers': _arrayToJson(providers),
'viewProviders': _arrayToJson(viewProviders),
'exports': _arrayToJson(exports),
'queries': _arrayToJson(queries),
'viewQueries': _arrayToJson(viewQueries)
};
Expand Down Expand Up @@ -724,6 +733,7 @@ CompileDirectiveMetadata createHostComponentMeta(
selector: '*',
providers: [],
viewProviders: [],
exports: [],
queries: [],
viewQueries: []);
}
Expand Down
1 change: 1 addition & 0 deletions lib/src/compiler/directive_normalizer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class DirectiveNormalizer {
lifecycleHooks: directive.lifecycleHooks,
providers: directive.providers,
viewProviders: directive.viewProviders,
exports: directive.exports,
queries: directive.queries,
viewQueries: directive.viewQueries,
template: normalizedTemplate));
Expand Down
20 changes: 20 additions & 0 deletions lib/src/compiler/expression_parser/ast.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'package:angular2/src/compiler/compile_metadata.dart';

class AST {
dynamic visit(AstVisitor visitor, [dynamic context = null]) {
return null;
Expand All @@ -12,6 +14,15 @@ class EmptyExpr extends AST {
void visit(AstVisitor visitor, [dynamic context = null]) {}
}

class StaticRead extends AST {
CompileIdentifierMetadata id;
StaticRead(this.id);

@override
dynamic visit(AstVisitor visitor, [dynamic context = null]) =>
visitor.visitStaticRead(this, context);
}

class ImplicitReceiver extends AST {
@override
dynamic visit(AstVisitor visitor, [dynamic context = null]) =>
Expand Down Expand Up @@ -247,6 +258,7 @@ abstract class AstVisitor {
dynamic visitPropertyWrite(PropertyWrite ast, dynamic context);
dynamic visitSafeMethodCall(SafeMethodCall ast, dynamic context);
dynamic visitSafePropertyRead(SafePropertyRead ast, dynamic context);
dynamic visitStaticRead(StaticRead ast, dynamic context);
}

class RecursiveAstVisitor implements AstVisitor {
Expand Down Expand Up @@ -368,6 +380,11 @@ class RecursiveAstVisitor implements AstVisitor {
return this.visitAll(ast.args as List<AST>, context);
}

@override
dynamic visitStaticRead(StaticRead ast, dynamic context) {
return null;
}

dynamic visitAll(List<AST> asts, dynamic context) {
asts.forEach((ast) => ast.visit(this, context));
return null;
Expand All @@ -378,6 +395,9 @@ class AstTransformer implements AstVisitor {
@override
AST visitImplicitReceiver(ImplicitReceiver ast, dynamic context) => ast;

@override
AST visitStaticRead(StaticRead ast, dynamic context) => ast;

@override
AST visitInterpolation(Interpolation ast, dynamic context) =>
new Interpolation(ast.strings, this._visitAll(ast.expressions));
Expand Down
81 changes: 52 additions & 29 deletions lib/src/compiler/expression_parser/parser.dart
Original file line number Diff line number Diff line change
@@ -1,33 +1,35 @@
import 'package:angular2/src/compiler/compile_metadata.dart';
import "package:angular2/src/core/di/decorators.dart" show Injectable;
import "package:angular2/src/facade/exceptions.dart" show BaseException;
import "package:angular2/src/facade/lang.dart" show jsSplit;

import "ast.dart"
show
AST,
EmptyExpr,
ImplicitReceiver,
PropertyRead,
PropertyWrite,
SafePropertyRead,
LiteralPrimitive,
ASTWithSource,
AstVisitor,
Binary,
PrefixNot,
Conditional,
IfNull,
BindingPipe,
Chain,
Conditional,
EmptyExpr,
FunctionCall,
IfNull,
ImplicitReceiver,
Interpolation,
KeyedRead,
KeyedWrite,
LiteralArray,
LiteralMap,
Interpolation,
LiteralPrimitive,
MethodCall,
PrefixNot,
PropertyRead,
PropertyWrite,
SafeMethodCall,
FunctionCall,
TemplateBinding,
ASTWithSource,
AstVisitor;
SafePropertyRead,
StaticRead,
TemplateBinding;
import "lexer.dart"
show
Lexer,
Expand Down Expand Up @@ -75,20 +77,24 @@ class Parser {

Parser(this._lexer);

ASTWithSource parseAction(String input, dynamic location) {
ASTWithSource parseAction(String input, dynamic location,
Map<String, CompileIdentifierMetadata> exports) {
this._checkNoInterpolation(input, location);
var tokens = _lexer.tokenize(this._stripComments(input));
var ast = new _ParseAST(input, location, tokens, true).parseChain();
var ast =
new _ParseAST(input, location, tokens, true, exports).parseChain();
return new ASTWithSource(ast, input, location);
}

ASTWithSource parseBinding(String input, dynamic location) {
var ast = this._parseBindingAst(input, location);
ASTWithSource parseBinding(String input, dynamic location,
Map<String, CompileIdentifierMetadata> exports) {
var ast = this._parseBindingAst(input, location, exports);
return new ASTWithSource(ast, input, location);
}

ASTWithSource parseSimpleBinding(String input, String location) {
var ast = this._parseBindingAst(input, location);
ASTWithSource parseSimpleBinding(String input, String location,
Map<String, CompileIdentifierMetadata> exports) {
var ast = this._parseBindingAst(input, location, exports);
if (!SimpleExpressionChecker.check(ast)) {
throw new ParseException(
"Host binding expression can only contain field access and constants",
Expand All @@ -98,27 +104,30 @@ class Parser {
return new ASTWithSource(ast, input, location);
}

AST _parseBindingAst(String input, String location) {
AST _parseBindingAst(String input, String location,
Map<String, CompileIdentifierMetadata> exports) {
this._checkNoInterpolation(input, location);
var tokens = this._lexer.tokenize(this._stripComments(input));
return new _ParseAST(input, location, tokens, false).parseChain();
return new _ParseAST(input, location, tokens, false, exports).parseChain();
}

TemplateBindingParseResult parseTemplateBindings(
String input, dynamic location) {
TemplateBindingParseResult parseTemplateBindings(String input,
dynamic location, Map<String, CompileIdentifierMetadata> exports) {
var tokens = this._lexer.tokenize(input);
return new _ParseAST(input, location, tokens, false)
return new _ParseAST(input, location, tokens, false, exports)
.parseTemplateBindings();
}

ASTWithSource parseInterpolation(String input, dynamic location) {
ASTWithSource parseInterpolation(String input, dynamic location,
Map<String, CompileIdentifierMetadata> exports) {
var split = this.splitInterpolation(input, location);
if (split == null) return null;
var expressions = [];
for (var i = 0; i < split.expressions.length; ++i) {
var tokens =
this._lexer.tokenize(this._stripComments(split.expressions[i]));
var ast = new _ParseAST(input, location, tokens, false).parseChain();
var ast =
new _ParseAST(input, location, tokens, false, exports).parseChain();
expressions.add(ast);
}
return new ASTWithSource(
Expand Down Expand Up @@ -200,8 +209,12 @@ class _ParseAST {
dynamic location;
List<dynamic> tokens;
bool parseAction;
Map<String, CompileIdentifierMetadata> exports;
num index = 0;
_ParseAST(this.input, this.location, this.tokens, this.parseAction);

_ParseAST(
this.input, this.location, this.tokens, this.parseAction, this.exports);

Token peek(num offset) {
var i = this.index + offset;
return i < this.tokens.length ? this.tokens[i] : EOF;
Expand Down Expand Up @@ -485,7 +498,15 @@ class _ParseAST {
} else if (this.next.isCharacter($LBRACE)) {
return this.parseLiteralMap();
} else if (this.next.isIdentifier()) {
return this.parseAccessMemberOrMethodCall(_implicitReceiver, false);
AST receiver = _implicitReceiver;
if (exports != null) {
var identifier = this.next.strValue;
if (exports.containsKey(identifier)) {
this.advance();
return new StaticRead(exports[identifier]);
}
}
return this.parseAccessMemberOrMethodCall(receiver, false);
} else if (this.next.isNumber()) {
var value = this.next.toNumber();
this.advance();
Expand Down Expand Up @@ -672,6 +693,8 @@ class SimpleExpressionChecker implements AstVisitor {
@override
void visitImplicitReceiver(ImplicitReceiver ast, dynamic context) {}
@override
void visitStaticRead(StaticRead ast, dynamic context) {}
@override
void visitInterpolation(Interpolation ast, dynamic context) {
this.simple = false;
}
Expand Down
14 changes: 9 additions & 5 deletions lib/src/compiler/provider_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import 'package:source_span/source_span.dart';

import "compile_metadata.dart"
show
CompileTypeMetadata,
CompileTokenMap,
CompileDiDependencyMetadata,
CompileDirectiveMetadata,
CompileIdentifierMetadata,
CompileProviderMetadata,
CompileQueryMetadata,
CompileTokenMap,
CompileTokenMetadata,
CompileProviderMetadata,
CompileDirectiveMetadata,
CompileDiDependencyMetadata;
CompileTypeMetadata;
import "identifiers.dart" show Identifiers, identifierToken;
import "parse_util.dart" show ParseError;
import "template_ast.dart"
Expand Down Expand Up @@ -63,6 +64,7 @@ class ProviderElementContext implements ElementProviderUsage {
final _transformedProviders = new CompileTokenMap<ProviderAst>();
final _seenProviders = new CompileTokenMap<bool>();
CompileTokenMap<ProviderAst> _allProviders;
Map<String, CompileIdentifierMetadata> _exports;
Map<String, String> _attrs;
bool _requiresViewContainer = false;

Expand Down Expand Up @@ -139,6 +141,8 @@ class ProviderElementContext implements ElementProviderUsage {

bool hasNonLocalRequest(ProviderAst providerAst) => true;

Map<String, CompileIdentifierMetadata> get exports => _exports;

void _addQueryReadsTo(
CompileTokenMetadata token, CompileTokenMap<bool> queryReadTokens) {
for (var query in _getQueriesFor(token)) {
Expand Down
Loading

0 comments on commit 0a28527

Please sign in to comment.